Compare commits

..

No commits in common. "master" and "0.2.6" have entirely different histories.

687 changed files with 7119 additions and 165973 deletions

View File

@ -1,48 +0,0 @@
version: 0.2.7.build{build}
image: Visual Studio 2019
clone_folder: C:\projects\welsonjs
environment:
ORGANIZATION_ID: 8ee5ec82-36dc-4619-ac33-5bc1117428fe
PROJECT_SLUG: welsonjs
ARTIFACT_CONFIGURATION_SLUG: initial
matrix:
- CONFIGURATION: Debug
SIGNING_POLICY_SLUG: test-signing
- CONFIGURATION: Release
SIGNING_POLICY_SLUG: release-signing
before_build:
- nuget restore WelsonJS.Toolkit
build_script:
- msbuild "C:\projects\welsonjs\WelsonJS.Toolkit\WelsonJS.Toolkit.sln" /verbosity:minimal /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" /p:Configuration=%CONFIGURATION% /p:Platform="x86"
after_build:
- cmd: mkdir artifacts
#- cmd: xcopy /s /y WelsonJS.Toolkit\WelsonJS.Toolkit\bin\x86\%CONFIGURATION%\* artifacts\
- cmd: xcopy /s /y WelsonJS.Toolkit\WelsonJS.Service\bin\x86\%CONFIGURATION%\* artifacts\
- cmd: xcopy /s /y WelsonJS.Toolkit\WelsonJS.Launcher\bin\x86\%CONFIGURATION%\* artifacts\
- cmd: xcopy /s /y WelsonJS.Toolkit\EsentInterop\bin\%CONFIGURATION%\* artifacts\
- cmd: nuget pack WelsonJS.Toolkit\WelsonJS.Toolkit\ -properties Configuration=%CONFIGURATION% -properties Platform=x86 -OutputDirectory artifacts\
- cmd: 7z a artifacts.zip artifacts\*
artifacts:
- path: artifacts.zip
name: WelsonJS.Toolkit
deploy:
- provider: Webhook
url: https://app.signpath.io/API/v1/%ORGANIZATION_ID%/Integrations/AppVeyor?ProjectSlug=%PROJECT_SLUG%&SigningPolicySlug=%SIGNING_POLICY_SLUG%&ArtifactConfigurationSlug=%ARTIFACT_CONFIGURATION_SLUG%
authorization:
secure: nABfe+lksIRfS7lVnkq3EdIYNH8KOka+5ZFTUJqUW2nckBubhrlAXarbCPJHLp9FWWf3zxAWhNwT0It+qyqPRQ==
notifications:
- provider: Email
to:
- gnh1201@catswords.re.kr
subject: 'Build #{{build}} {{status}}'
on_build_success: false
on_build_failure: true

2
.github/FUNDING.yml vendored
View File

@ -1,2 +0,0 @@
github: gnh1201
custom: ['https://gnh1201.link']

View File

@ -1,38 +0,0 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

View File

@ -1,20 +0,0 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@ -32,7 +32,7 @@ jobs:
strategy:
fail-fast: false
matrix:
language: [ 'javascript' ]
language: [ 'csharp', 'javascript', 'python' ]
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
# Learn more about CodeQL language support at https://git.io/codeql-language-support
@ -42,7 +42,7 @@ jobs:
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v2
uses: github/codeql-action/init@v1
with:
languages: ${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
@ -53,7 +53,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
uses: github/codeql-action/autobuild@v2
uses: github/codeql-action/autobuild@v1
# Command-line programs to run using the OS shell.
# 📚 https://git.io/JvXDl
@ -67,4 +67,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2
uses: github/codeql-action/analyze@v1

View File

@ -1,23 +0,0 @@
name: AI Code Review
on:
pull_request:
types: [opened, synchronize, reopened]
issues:
types: [opened, reopened]
jobs:
repofix:
runs-on: ubuntu-latest
steps:
- name: Run RepoFixAI
uses: Manav916/llm-code-review@main
with:
groq_api_key: ${{ secrets.GROQ_API_KEY }}
groq_model: 'llama-3.3-70b-versatile'
github_token: ${{ secrets.GITHUB_TOKEN }}
# exclude_extensions: 'txt'
repo_owner: ${{ github.repository_owner }}
repo_name: ${{ github.event.repository.name }}
event_number: ${{ github.event.number || github.event.issue.number }} # when listening for both pull requests and issues
event_name: ${{ github.event_name }}

15
.gitignore vendored
View File

@ -103,13 +103,8 @@ dist
# TernJS port file
.tern-port
# user private assets
bin
data/*-apikey.txt
data/*.nomedia.txt
app/assets/img/_templates
app/assets/img/_captured
settings.ini
defaultService.js
lib/*.private.js
data/python313.zip
# Custom directories and files
bin/
packages/
config.xml
staticip.xml

View File

@ -1,3 +0,0 @@
sonar.issue.ignore.multicriteria=e1
sonar.issue.ignore.multicriteria.e1.ruleKey=javascript:S3504
sonar.issue.ignore.multicriteria.e1.resourceKey=**

View File

@ -1,11 +0,0 @@
cff-version: 1.2.0
message: "If you use this software, please cite it as below."
authors:
- family-names: "Go"
given-names: "Namhyeon"
orcid: "https://orcid.org/0009-0006-8421-0911"
title: "WelsonJS"
version: 0.2.7.12
doi: 10.5281/zenodo.11382384
date-released: 2024-05-29
url: "https://github.com/gnh1201/welsonjs"

View File

@ -1,70 +0,0 @@
# Code of Conduct - WelsonJS
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to make participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, or to ban
temporarily or permanently any contributor for other behaviors that they deem
inappropriate, threatening, offensive, or harmful.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at <abuse@catswords.net>.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant](https://contributor-covenant.org/), version
[1.4](https://www.contributor-covenant.org/version/1/4/code-of-conduct/code_of_conduct.md) and
[2.0](https://www.contributor-covenant.org/version/2/0/code_of_conduct/code_of_conduct.md),
and was generated by [contributing-gen](https://github.com/bttger/contributing-gen).

View File

@ -1,146 +0,0 @@
<!-- omit in toc -->
# Contributing to WelsonJS
First off, thanks for taking the time to contribute! ❤️
All types of contributions are encouraged and valued. See the [Table of Contents](#table-of-contents) for different ways to help and details about how this project handles them. Please make sure to read the relevant section before making your contribution. It will make it a lot easier for us maintainers and smooth out the experience for all involved. The community looks forward to your contributions. 🎉
> And if you like the project, but just don't have time to contribute, that's fine. There are other easy ways to support the project and show your appreciation, which we would also be very happy about:
> - Star the project
> - Tweet about it
> - Refer this project in your project's readme
> - Mention the project at local meetups and tell your friends/colleagues
<!-- omit in toc -->
## Table of Contents
- [Code of Conduct](#code-of-conduct)
- [I Have a Question](#i-have-a-question)
- [I Want To Contribute](#i-want-to-contribute)
- [Reporting Bugs](#reporting-bugs)
- [Suggesting Enhancements](#suggesting-enhancements)
- [Your First Code Contribution](#your-first-code-contribution)
- [Improving The Documentation](#improving-the-documentation)
- [Styleguides](#styleguides)
- [Commit Messages](#commit-messages)
- [Join The Project Team](#join-the-project-team)
## Code of Conduct
This project and everyone participating in it is governed by the [WelsonJS Code of Conduct](https://github.com/gnh1201/welsonjs/blob/master/CODE_OF_CONDUCT.md).
By participating, you are expected to uphold this code. Please report unacceptable behavior to <abuse@catswords.net>.
## I Have a Question
> If you want to ask a question, we assume that you have read the available [Documentation](https://catswords-oss.rdbl.io/5719744820/5330609327).
Before you ask a question, it is best to search for existing [Issues](https://github.com/gnh1201/welsonjs/issues) that might help you. In case you have found a suitable issue and still need clarification, you can write your question in this issue. It is also advisable to search the internet for answers first.
If you then still feel the need to ask a question and need clarification, we recommend the following:
- Open an [Issue](https://github.com/gnh1201/welsonjs/issues/new).
- Provide as much context as you can about what you're running into.
- Provide project and platform versions (nodejs, npm, etc), depending on what seems relevant.
We will then take care of the issue as soon as possible.
You might want to create a separate issue tag for questions and include it in this description. People should then tag their issues accordingly.
Depending on how large the project is, you may want to outsource the questioning, e.g. to Stack Overflow. You may add additional contact and information possibilities:
- ActivityPub
- Stack Overflow tag or Public Forums
- E-Mail List
## I Want To Contribute
> ### Legal Notice <!-- omit in toc -->
> When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the project license.
### Reporting Bugs
<!-- omit in toc -->
#### Before Submitting a Bug Report
A good bug report shouldn't leave others needing to chase you up for more information. Therefore, we ask you to investigate carefully, collect information and describe the issue in detail in your report. Please complete the following steps in advance to help us fix any potential bug as fast as possible.
- Make sure that you are using the latest version.
- Determine if your bug is really a bug and not an error on your side e.g. using incompatible environment components/versions (Make sure that you have read the [documentation](https://catswords.social/@catswords_oss). If you are looking for support, you might want to check [this section](#i-have-a-question)).
- To see if other users have experienced (and potentially already solved) the same issue you are having, check if there is not already a bug report existing for your bug or error in the [bug tracker](https://github.com/gnh1201/welsonjs/issues?q=label%3Abug).
- Also make sure to search the internet (including Stack Overflow) to see if users outside of the GitHub community have discussed the issue.
- Collect information about the bug:
- Stack trace (Traceback)
- OS, Platform and Version (Windows, Linux, macOS, x86, ARM)
- Version of the interpreter, compiler, SDK, runtime environment, package manager, depending on what seems relevant.
- Possibly your input and the output
- Can you reliably reproduce the issue? And can you also reproduce it with older versions?
<!-- omit in toc -->
#### How Do I Submit a Good Bug Report?
> You must never report security related issues, vulnerabilities or bugs including sensitive information to the issue tracker, or elsewhere in public. Instead sensitive bugs must be sent by email to <abuse@catswords.net>.
<!-- You may add a PGP key to allow the messages to be sent encrypted as well. -->
We use GitHub issues to track bugs and errors. If you run into an issue with the project:
- Open an [Issue](https://github.com/gnh1201/welsonjs/issues/new). (Since we can't be sure at this point whether it is a bug or not, we ask you not to talk about a bug yet and not to label the issue.)
- Explain the behavior you would expect and the actual behavior.
- Please provide as much context as possible and describe the *reproduction steps* that someone else can follow to recreate the issue on their own. This usually includes your code. For good bug reports you should isolate the problem and create a reduced test case.
- Provide the information you collected in the previous section.
Once it's filed:
- The project team will label the issue accordingly.
- A team member will try to reproduce the issue with your provided steps. If there are no reproduction steps or no obvious way to reproduce the issue, the team will ask you for those steps and mark the issue as `needs-repro`. Bugs with the `needs-repro` tag will not be addressed until they are reproduced.
- If the team is able to reproduce the issue, it will be marked `needs-fix`, as well as possibly other tags (such as `critical`), and the issue will be left to be [implemented by someone](#your-first-code-contribution).
<!-- You might want to create an issue template for bugs and errors that can be used as a guide and that defines the structure of the information to be included. If you do so, reference it here in the description. -->
### Suggesting Enhancements
This section guides you through submitting an enhancement suggestion for WelsonJS, **including completely new features and minor improvements to existing functionality**. Following these guidelines will help maintainers and the community to understand your suggestion and find related suggestions.
<!-- omit in toc -->
#### Before Submitting an Enhancement
- Make sure that you are using the latest version.
- Read the [documentation](https://catswords-oss.rdbl.io/5719744820/5330609327) carefully and find out if the functionality is already covered, maybe by an individual configuration.
- Perform a [search](https://github.com/gnh1201/welsonjs/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one.
- Find out whether your idea fits with the scope and aims of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Keep in mind that we want features that will be useful to the majority of our users and not just a small subset. If you're just targeting a minority of users, consider writing an add-on/plugin library.
<!-- omit in toc -->
#### How Do I Submit a Good Enhancement Suggestion?
Enhancement suggestions are tracked as [GitHub issues](https://github.com/gnh1201/welsonjs/issues).
- Use a **clear and descriptive title** for the issue to identify the suggestion.
- Provide a **step-by-step description of the suggested enhancement** in as many details as possible.
- **Describe the current behavior** and **explain which behavior you expected to see instead** and why. At this point you can also tell which alternatives do not work for you.
- You may want to **include screenshots and animated GIFs** which help you demonstrate the steps or point out the part which the suggestion is related to. You can use [this tool](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux. <!-- this should only be included if the project has a GUI -->
- **Explain why this enhancement would be useful** to most WelsonJS users. You may also want to point out the other projects that solved it better and which could serve as inspiration.
<!-- You might want to create an issue template for enhancement suggestions that can be used as a guide and that defines the structure of the information to be included. If you do so, reference it here in the description. -->
### Your First Code Contribution
Just Notepad, in Windows machine.
## Styleguides
### Commit Messages
Flexible. We will respect your style.
## Join The Project Team
Contact us:
* ActivityPub [@catswords_oss@catswords.social](https://catswords.social/@catswords_oss)
* XMPP [catswords@conference.omemo.id](xmpp:catswords@conference.omemo.id?join)
* [Join Catswords OSS on Microsoft Teams (teams.live.com)](https://teams.live.com/l/community/FEACHncAhq8ldnojAI)
* [Join Catswords OSS #welsonjs on Discord (discord.gg)](https://discord.gg/XKG5CjtXEj)
## Attribution
This guide is based on the **contributing-gen**. [Make your own](https://github.com/bttger/contributing-gen)!

5
FUNDING.yml Normal file
View File

@ -0,0 +1,5 @@
# These are supported funding model platforms
github: gnh1201, catswords
patreon: catswords # Replace with a single Patreon username
custom: ['https://www.buymeacoffee.com/catswords']

View File

@ -0,0 +1,4 @@
@echo off
reg add "HKCU\Software\Microsoft\Internet Explorer\Styles" /f
reg add "HKCU\Software\Microsoft\Internet Explorer\Styles" /v "MaxScriptStatements" /t REG_DWORD /d 0xFFFFFFFF /f

873
LICENSE
View File

@ -1,622 +1,281 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Version 2, June 1991
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
13. Use with the GNU Affero General Public License.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
14. Revised Versions of this License.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
NO WARRANTY
15. Disclaimer of Warranty.
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
@ -628,15 +287,15 @@ free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@ -644,31 +303,37 @@ the "copyright" line and a pointer to where the full notice is found.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<https://www.gnu.org/licenses/>.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<https://www.gnu.org/licenses/why-not-lgpl.html>.
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@ -1,4 +1,5 @@
Microsoft Reciprocal License (Ms-RL)
Microsoft Reciprocal License (MS-RL)
SPDX Short identifier: MS-RL
This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software.
@ -12,14 +13,14 @@ A "contributor" is any person that distributes its contribution under this licen
"Licensed patents" are a contributor's patent claims that read directly on its contribution.
2. Grant of Rights
(A) Copyright Grant - Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
(A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create.
(B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software.
3. Conditions and Limitations
(A) Reciprocal Grants - For any file you distribute that contains code from the software (in source code or binary format), you must provide recipients the source code to that file along with a copy of this license, which license will govern that file. You may license other files that are entirely your own work and do not contain code from the software under any terms you choose.
(A) Reciprocal Grants- For any file you distribute that contains code from the software (in source code or binary format), you must provide recipients the source code to that file along with a copy of this license, which license will govern that file. You may license other files that are entirely your own work and do not contain code from the software under any terms you choose.
(B) No Trademark License - This license does not grant you rights to use any contributors' name, logo, or trademarks.
(B) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks.
(C) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically.
@ -28,3 +29,35 @@ A "contributor" is any person that distributes its contribution under this licen
(E) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license.
(F) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement.
Microsoft 상호 라이선스(MS-RL)
SPDX 짧은 식별자: MS-RL
이 라이센스는 함께 제공되는 소프트웨어의 사용에 적용됩니다. 소프트웨어를 사용하는 경우 이 라이센스에 동의하는 것입니다. 라이센스에 동의하지 않으면 소프트웨어를 사용하지 마십시오.
1. 정의
"복제", "복제물", "파생 저작물" 및 "배포"라는 용어는 여기에서 미국 저작권법과 동일한 의미를 갖습니다.
"기여"은 원본 소프트웨어 또는 소프트웨어에 대한 추가 또는 변경 사항입니다.
"기여자"는 이 라이선스에 따라 기여를 배포하는 모든 사람입니다.
"라이선스 지적재산권"은 기여에 대해 직접 읽는 기여자의 지적재산권 주장입니다.
2. 권리 부여
(A) 저작권 부여 - 섹션 3의 라이선스 조건 및 제한 사항을 포함하여 이 라이선스의 조건에 따라 각 기여자는 자신의 기여를 복제하고 파생 작업을 준비할 수 있는 비독점적이고 전세계적인 로열티 없는 저작권 라이선스를 부여합니다. 기여 및 귀하가 만든 기여 또는 파생 작업을 배포합니다.
(B) 지적재산권 부여 - 섹션 3의 라이선스 조건 및 제한 사항을 포함하여 이 라이선스의 조건에 따라 각 기여자는 라이선스가 부여된 지적재산권에 따라 귀하에게 비독점적이고 전 세계적으로 사용료가 없는 라이선스를 부여합니다. 여기에는 판매, 판매 제안, 수입 및 또는 소프트웨어에 대한 기여 또는 소프트웨어 기여의 파생물을 처분하는 행위를 포함합니다.
3. 조건 및 제한
(A) 상호 부여 - 소프트웨어의 코드(소스코드 또는 바이너리 형식)가 포함된 배포하는 모든 파일의 경우 해당 파일에 적용되는 라이선스의 사본과 함께 해당 파일의 소스코드를 수신자에게 제공해야 합니다. . 귀하는 전적으로 귀하의 저작물이며 귀하가 선택한 조건에 따라 소프트웨어의 코드를 포함하지 않는 다른 파일에 라이선스를 부여할 수 있습니다.
(B) 상표 사용권 없음 - 이 사용권은 기여자의 이름, 로고 또는 상표를 사용할 수 있는 권한을 부여하지 않습니다.
(C) 귀하가 소프트웨어에 의해 침해되었다고 주장하는 지적재산권에 대해 기여자에 대해 지적재산권 청구를 제기하는 경우 해당 기여자의 소프트웨어에 대한 귀하의 지적재산권 라이선스는 자동으로 종료됩니다.
(D) 소프트웨어의 일부를 배포하는 경우 소프트웨어에 있는 모든 저작권, 지적재산권, 상표 및 귀속 고지를 보유해야 합니다.
(E) 소프트웨어의 일부를 소스코드 형식으로 배포하는 경우 배포와 함께 이 라이센스의 전체 사본을 포함하여 이 라이센스 하에서만 그렇게 할 수 있습니다. 소프트웨어의 일부를 컴파일된 또는 개체 코드 형식으로 배포하는 경우 이 라이센스를 준수하는 라이센스 하에서만 배포할 수 있습니다.
(F) 소프트웨어는 "있는 그대로" 사용이 허가됩니다. 당신은 그것을 사용할 위험을 감수합니다. 기여자는 명시적 보증, 보증 또는 조건을 제공하지 않습니다. 귀하는 현지 법률에 따라 이 라이선스가 변경할 수 없는 추가적인 소비자 권리를 가질 수 있습니다. 현지 법률에서 허용하는 범위 내에서 기여자는 상품성, 특정 목적에의 적합성 및 비침해성에 대한 묵시적 보증을 배제합니다.

241
README.md
View File

@ -1,105 +1,91 @@
# welsonjs
WelsonJS - Build a Windows app on the Windows built-in JavaScript engine.
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fgnh1201%2Fwelsonjs.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Fgnh1201%2Fwelsonjs?ref=badge_shield)
[![AppVeyor Status](https://ci.appveyor.com/api/projects/status/github/gnh1201/welsonjs?svg=true)](https://ci.appveyor.com/project/gnh1201/welsonjs)
[![DOI 10.5281/zenodo.11382384](https://zenodo.org/badge/DOI/10.5281/zenodo.11382384.svg)](https://doi.org/10.5281/zenodo.11382384)
[![ChatGPT available](https://img.shields.io/badge/ChatGPT-74aa9c?logo=openai&logoColor=white)](https://catswords-oss.rdbl.io/5719744820/5510319392)
[![Anthropic available](https://img.shields.io/badge/Anthropic-000000?logo=Anthropic&logoColor=white)](https://catswords-oss.rdbl.io/5719744820/5510319392)
[![Grok available](https://img.shields.io/badge/Grok-000000?logo=x&logoColor=white)](https://catswords-oss.rdbl.io/5719744820/5510319392)
[![Google Gemini available](https://img.shields.io/badge/Google%20Gemini-886FBF?logo=googlegemini&logoColor=fff)](https://catswords-oss.rdbl.io/5719744820/5510319392)
[![slideshare.net presentation](https://img.shields.io/badge/SlideShare-black?logo=slideshare)](https://www.slideshare.net/slideshow/welsonjs-javascript-framework-presentation-2024/276005486)
[![YouTube promotion video](https://img.shields.io/badge/YouTube-red?logo=youtube)](https://youtu.be/JavH7Dms8-U)
[![Discord chat](https://img.shields.io/discord/359930650330923008?logo=discord)](https://discord.gg/XKG5CjtXEj)
[![Open to work](https://img.shields.io/badge/%23-OPENTOWORK-green)](https://github.com/gnh1201/welsonjs/discussions/167)
We can build a Windows desktop app with JavaScript, TypeScript, ReScript, and HTML/CSS on WSH(Windows Script Host)
<img src="app/assets/img/logo.svg" height="32" alt=""/> WelsonJS - Build a Windows app on the Windows built-in JavaScript engine.
[![Buy me a coffee](https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png)](https://www.buymeacoffee.com/catswords/thanks-welsonjs-users)
![A Cover Image: Windows in 1999](https://ics.catswords.net/cover.png)
WelsonJS = ***W***indows + ***El***ectr***on***-like + ***Javascript(JS)***
Now, You can build a Windows desktop app with JavaScript, TypeScript, CoffeeScript, ReScript, and HTML/CSS on Windows built-in ECMAScript engine.
WelsonJS = ***W***indows + ***El***ectr***on***-like + ***Javascript(JS)*** + :heart:[Contributions](https://github.com/sponsors/gnh1201)
* :kissing_cat: [Download Latest WelsonJS Launcher (ics.catswords.net)](https://ics.catswords.net/welsonjs_launcher_latest.zip)
* :rocket: [Launch the WelsonJS environment on Microsoft Azure (azuremarketplace.microsoft.com)](https://azuremarketplace.microsoft.com/en-us/marketplace/apps/catswords.catswords-welsonjs-feb2025-02?tab=Overview)
**Note**: The default license for this project is GPL 3.0. However, if the GPL 3.0 license is not compatible with Microsoft products, it is subject to the MS-RL license.
## Sponsors
* :octocat: [GitHub Sponsors](https://github.com/sponsors/gnh1201), :coffee: [Buy me a coffee](https://buymeacoffee.com/catswords)
* <img src="https://ics.catswords.net/serpapi_logo_32.png" height="32" alt=""/> [SerpApi: Search API](https://serpapi.com/?utm_source=welsonjs) - Scrape search engines results with simple API.
* <img src="https://ics.catswords.net/logo_oss.gif" height="32" alt=""/> [Open SW Portal](https://oss.kr), NIPA National IT Industry Promotion Agency<sup>(정보통신산업진흥원)</sup>
* <img src="https://ics.catswords.net/signpath_logo.png" height="32" alt=""/> Free code signing provided by [SignPath.io](https://signpath.io), certificate by [SignPath Foundation](https://signpath.org/)
* <img src="https://ics.catswords.net/f1security_logo.png" height="32" alt=""/> [F1Security<sup>(에프원시큐리티)</sup>](https://f1security.co.kr/) provides [industry-leading](https://www.ksecurity.or.kr/kisis/subIndex/469.do) web security services.
* <img src="https://ics.catswords.net/microsoft_logo.png" height="32" alt=""/> [Microsoft ISV Success Program](https://www.microsoft.com/en-us/isv/isv-success), Grow your business with powerful tools.
* :zap: [Integrations](https://catswords-oss.rdbl.io/5719744820/8278298336) ([ScrapeOps](https://scrapeops.io?fpr=namhyeon75), [AviationStack](https://aviationstack.com?utm_source=FirstPromoter&utm_medium=Affiliate&fpr=namhyeon71), [Coupang](https://link.coupang.com/a/b7HV3V)...)
## System Requirements
* **Operating Systems**: Windows XP SP3 or later (Currently, Windows 11 24H2)
* For systems running Windows 2000 or earlier versions (e.g., 95, 98, Me), please contact us separately.
## Why Choose WelsonJS?
WelsonJS is an advanced JavaScript framework designed to operate in extreme conditions where conventional solutions may fail. Unlike traditional JavaScript frameworks, WelsonJS focuses on executing scripts in constrained environments, ensuring reliable performance even with minimal system resources.
### Key Features
* **Lightweight and Efficient**: Optimized for environments with limited computing power, WelsonJS delivers efficient script execution without unnecessary overhead.
* **Windows ECMAScript Compatibility**: Designed to run seamlessly on Windows-based systems, adhering to the ECMAScript standard while maintaining lightweight execution.
* **Standalone Execution**: Unlike well-known JavaScript runtimes, which require external dependencies, a WelsonJS application can operate as a self-contained app, making it suitable for embedded systems and isolated environments.
* **Security-Oriented**: Built with security in mind, ensuring controlled execution of scripts without compromising system integrity.
* **Minimalist Design**: WelsonJS strips away unnecessary complexities, focusing on core functionalities that maximize performance and reliability.
### Use Cases
* **Legacy System Integration**: WelsonJS provides a practical solution for running JavaScript on older Windows environments where modern frameworks are not feasible.
* **Automation and Scripting**: Ideal for executing scripts in constrained environments, enabling automated workflows and system-level scripting.
* **Embedded Applications**: Suitable for devices and systems with strict resource constraints, such as industrial controllers and embedded platforms.
* **Security-Focused Environments**: Useful in security-sensitive applications where dependencies on external network connections are limited.
* **Office Automation**: Suitable for office automation tasks using Microsoft Office and various LLM-based AI (such as ChatGPT).
WelsonJS is tailored for developers who need a reliable, lightweight JavaScript framework in environments where traditional solutions are impractical. Whether working with legacy systems, embedded devices, or security-critical applications, WelsonJS ensures that JavaScript remains a viable and efficient option.
Dual license notice: The default license for this project is GPL 3.0. However, if the GPL 3.0 license is not compatible with Microsoft products, it is subject to the MS-RL license.
## Structure
![The structure of the WelsonJS framework can be extended based on whether it operates in a console (command prompt) environment, a GUI (with HTML/CSS) environment, or a service environment, with the `app.js` file at its core.](https://ics.catswords.net/structure.png)
![Structure](app/assets/img/structure.png)
## Specifications
* Built-in transpilers: [TypeScript](https://www.typescriptlang.org/), [Rescript](https://rescript-lang.org/), [CoffeeScript 2](https://coffeescript.org/), [LiveScript](https://livescript.net/)
* **Ready to use on Windows machine immediately. No additional software installation is required.**
* **WelsonJS Launcher**: Manage instances (Like a container), User-defined variable editor, [Microsoft Monaco Editor](https://github.com/microsoft/monaco-editor) and [React](https://react.dev/) (Pre-embedded rich code editor), [Microsoft Copilot](https://copilot.microsoft.com), and [Azure AI Services](https://azure.microsoft.com/en-us/products/ai-services), Network tools (Whois, DNS Query, [Criminal IP CTI](https://www.criminalip.io/)) on the code editor.
* ES5(ECMAScript 5), XML, JSON, YAML compatibility: [core-js](https://github.com/zloirock/core-js), [JSON2.js](https://github.com/douglascrockford/JSON-js), [js-yaml](https://github.com/nodeca/js-yaml)
* HTML5 compatibility on the built-in HTML rendering engine: [html5shiv](https://github.com/aFarkas/html5shiv), [jquery-html5-placeholder-shim](https://github.com/parndt/jquery-html5-placeholder-shim), [Respond](https://github.com/scottjehl/Respond), [selectivizr](https://github.com/keithclark/selectivizr), [ExplorerCanvas](https://github.com/arv/ExplorerCanvas), [Modernizr](https://github.com/Modernizr/Modernizr)
* Classical CSS Frameworks: [cascadeframework](https://github.com/jslegers/cascadeframework), [golden-layout](https://github.com/golden-layout/golden-layout)
* WYSIWYG HTML Editor: [summernote](https://github.com/summernote/summernote)
* Included libraries: [jQuery](https://jquery.com/), [jQuery UI](https://jqueryui.com/), [jquery-toast-plugin](https://github.com/kamranahmedse/jquery-toast-plugin), [squel](https://github.com/hiddentao/squel), [jsrender](https://github.com/BorisMoore/jsrender), [linq](https://github.com/mihaifm/linq), [pegjs](https://github.com/pegjs/pegjs), [numbers.js](https://github.com/numbers/numbers.js)
* Compatible with modern JavaScript specifications: [module.exports](https://nodejs.org/api/modules.html#moduleexports), CommonJS, UMD compatibility, [NPM(Node Package Manager)](https://www.npmjs.com/) compatibility
* Support a device debugging protocol clients: [Chrome DevTools Protocol](https://chromedevtools.github.io/devtools-protocol/), [ADB(Android Debug Bridge)](https://source.android.com/docs/setup/build/adb)
* RPC(Remote Procedure Call) protocol clients: [gRPC](https://grpc.io/), [JSON-RPC 2.0](https://www.jsonrpc.org/specification)
* Various types of HTTP clients: [XHR(MSXML)](https://developer.mozilla.org/docs/Glossary/XMLHttpRequest), [cURL](https://curl.se/), [BITS](https://en.m.wikipedia.org/w/index.php?title=Background_Intelligent_Transfer_Service), [CERT](https://github.com/MicrosoftDocs/windowsserverdocs/blob/main/WindowsServerDocs/administration/windows-commands/certutil.md), [Web Proxy, SEO/SERP](https://catswords-oss.rdbl.io/5719744820/1706431912)
* The native toolkit for Windows environments: Write a Windows Service Application with JavaScript, Control a window handle, Cryptography (e.g., [ISO/IEC 18033-3:2010](https://www.iso.org/standard/54531.html) aka. [HIGHT](https://seed.kisa.or.kr/kisa/algorithm/EgovHightInfo.do)), [Named Shared Memory](https://learn.microsoft.com/en-us/windows/win32/memory/creating-named-shared-memory) based [IPC](https://qiita.com/gnh1201/items/4e70dccdb7adacf0ace5), [NuGet package](https://www.nuget.org/packages/WelsonJS.Toolkit)
* Generative AI integrations: [Multiple LLM and sLLM](https://catswords-oss.rdbl.io/5719744820/5510319392) (e.g., ChatGPT, Claude, ...)
* Aviation Data integrations: [AviationStack](https://aviationstack.com?utm_source=FirstPromoter&utm_medium=Affiliate&fpr=namhyeon71), [SerpApi Google Flights API](https://serpapi.com/google-flights-api?utm_source=welsonjs)
* VM infrastructure tool integrations: [OVFTool for Broadcom/VMware infrastructures](https://developer.broadcom.com/tools/open-virtualization-format-ovf-tool/latest)
* ***:fire: NEW!*** Windows bulit-in database engine AKA. [ESENT (ESE) database](https://learn.microsoft.com/en-us/windows/win32/extensible-storage-engine/database-overview) interface library (WelsonJS.Esent)
* Everything you can imagine.
- Built-in transpilers: [TypeScript](https://www.typescriptlang.org/), [Rescript](https://rescript-lang.org/), [CoffeeScript 2](https://coffeescript.org/), [LiveScript](https://livescript.net/)
- Ready to use on Windows machine immediately. No require additional software installation.
- ES5(ECMAScript 5), XML, JSON, YAML compatibility
- [github:zloirock/core-js](https://github.com/zloirock/core-js)
- [github:douglascrockford/JSON-js](https://github.com/douglascrockford/JSON-js) (aka. JSON2.js)
- [github:nodeca/js-yaml](https://github.com/nodeca/js-yaml)
- HTML5, CSS3 compatibility
- [github:aFarkas/html5shiv](https://github.com/aFarkas/html5shiv)
- [github:parndt/jquery-html5-placeholder-shim](https://github.com/parndt/jquery-html5-placeholder-shim)
- [github:scottjehl/Respond](https://github.com/scottjehl/Respond)
- [github:keithclark/selectivizr](https://github.com/keithclark/selectivizr)
- [github:arv/ExplorerCanvas](https://github.com/arv/ExplorerCanvas)
- [github:etianen/html5media](https://github.com/etianen/html5media)
- [github:Modernizr/Modernizr](https://github.com/Modernizr/Modernizr)
- Default CSS Framework
- [github:jslegers/cascadeframework](https://github.com/jslegers/cascadeframework)
- Included libraries
- [jQuery](https://jquery.com/)
- [jQuery UI](https://jqueryui.com/)
- [github:kamranahmedse/jquery-toast-plugin](https://github.com/kamranahmedse/jquery-toast-plugin)
- [github:hiddentao/squel](https://github.com/hiddentao/squel)
- [github:BorisMoore/jsrender](https://github.com/BorisMoore/jsrender)
- [Includes binaries](https://github.com/gnh1201/welsonjs/blob/master/bin/README.MD)
- [module.exports](https://nodejs.org/en/knowledge/getting-started/what-is-require/), CommonJS, UMD compatibility
- [NPM](https://www.npmjs.com/) compatibility
- [gRPC](https://grpc.io/) protocol support (New feature in 2023) [see video demo](https://youtu.be/GqbU5JKuLac)
## Quick start
## Included libraries
- lib/std (Standard library)
- lib/system (System library)
- lib/base64 (BASE64 Encode and Decode)
- lib/db (Database interface)
- lib/file (File I/O interface)
- lib/http (HTTP interface)
- lib/json (JSON Encode and Decode)
- lib/registry (Windows Registry interface)
- lib/security (Security Policy interface)
- lib/sendmail (Sendmail interface with 3rdparty)
- lib/shell (Command Prompt interface)
- lib/timer (`setTimeout` polyfills)
- lib/powershell (Windows Powershell interface)
- lib/service (Windows Service interface)
- lib/oldbrowser (ES5/ES6, HTML/JS/CSS compatibility)
- lib/uri (URI scheme interface)
- lib/winlibs (Windows DLL(Dynamic-link library) interface)
- lib/autohotkey ([AutoHotkey](https://www.autohotkey.com/) interface)
- lib/autoit ([AutoIt3/AutoItX](https://www.autoitscript.com/) interface)
- lib/shadowsocks ([Shadowsocks](https://shadowsocks.org/) interface)
- lib/excel (Microsoft Excel interface)
- lib/vbscript (VBScript interface)
- lib/wintap (Windows-TAP interface)
- lib/tun2socks (TUN2SOCKS interface)
- lib/hosts (Hosts file interface)
- lib/gtk (GTK/GladeXML server GUI interface)
- lib/chrome (Chrome Web Browser Debugging interface)
- lib/toolkit (`WelsonJS.Toolkit` native component)
- lib/pipe-ipc (PIPE-based IPC(Inter-Process Communication) implementation)
## Make your own `sayhello` example
### 1. Write a file `lib/sayhello.js`
```js
// lib/sayhello.js
function say() {
console.log("hello");
}
exports.say = say;
exports.VERSIONINFO = "SayHello (sayhello.js) version 0.1";
exports.AUTHOR = "gnh1201@catswords.re.kr";
```
exports.VERSIONINFO = "SayHello Library (sayhello.js) version 0.1
exports.global = global;
exports.require = global.require;
exports.say = function() {
console.log("hello");
}
```
### 2. Write a file `sayhello.js`
```js
// sayhello.js
```
var SayHello = require("lib/sayhello");
function main() {
@ -111,76 +97,43 @@ function main() {
exports.main = main;
```
### 3. Execute script on the console
```cmd
C:\Users\JohnDoe\Documents\GitHub\welsonjs> cscript app.js sayhello
### 3. Execute file on the command prompt
```
C:\Users\John\Documents\GitHub\welsonjs> cscript app.js sayhello
calling say()
hello
ended say()
```
## How to release my application?
The WelsonJS framework suggests the following application release methods:
* **Compress to Zip, and use the launcher**: Compress the files and directories necessary for running the project into a Zip file, and distribute it along with the [WelsonJS Launcher](https://catswords-oss.rdbl.io/5719744820/4131485779).
* **Build a setup file**: Use [Inno Setup](https://jrsoftware.org/isinfo.php). The setup profile (the `setup.iss` file) is already included.
* **Copy all directories and files**: This is the simplest and most straightforward method.
## How to make your own setup file
- Please check `setup.iss` file it could be compile with [Inno Setup](https://jrsoftware.org/isinfo.php)
## Screenshots
![(Screenshot 1) GUI environment](https://ics.catswords.net/screenshot.png)
![Screenshot 1](app/assets/img/screenshot.png)
![(Screenshot 2) Command-line environment](https://ics.catswords.net/screenshot2.png)
## Thanks!
![Thanks 1](app/assets/img/thanks.png)
![(Screenshot 3) WelsonJS with Microsoft Excel](https://ics.catswords.net/screenshot3.png)
- https://www.facebook.com/javascript4u/posts/1484014618472735
- https://python5.com/q/xtbsqjxb
![(Screenshot 4) Write a Windows Services with JavaScript](https://ics.catswords.net/screenshot4.png)
## Related projects
- [gnh1201/wsh-js-gtk](https://github.com/gnh1201/wsh-js-gtk) - GTK GUI ported to Windows Scripting Host - Javascript (Microsoft JScript) (wsh-js)
- [gnh1201/wsh-json](https://github.com/gnh1201/wsh-json) - JSON stringify/parse (encode/decode) for Windows Scripting Host
- [redskyit/wsh-appjs](https://github.com/redskyit/wsh-appjs) - require-js and app framework for Windows Scripting Host JavaScript
- [JohnLaTwC's gist](https://gist.github.com/JohnLaTwC/4315bbbd89da0996f5c08c032b391799) - JavaScript RAT
- [JSMan-/JS-Framework](https://github.com/JSMan-/JS-Framework) - No description
- [iconjack/setTimeout-for-windows-script-host](https://github.com/iconjack/setTimeout-for-windows-script-host) - Replacement for the missing setTimeout and clearTimeout function in Windows Script Host
- [johnjohnsp1/WindowsScriptHostExtension](https://github.com/johnjohnsp1/WindowsScriptHostExtension) - Inject DLL Prototype using Microsoft.Windows.ACTCTX COM Object
- [kuntashov/jsunit](https://github.com/kuntashov/jsunit) - JSUnit port for Windows Scripting Host
- [nickdoth/WSHHttpServer](https://github.com/nickdoth/WSHHttpServer) - HTTP server based on Windows Script Host
![(Screenshot 5) Template Matching on the computer screen](https://ics.catswords.net/screenshot5.png)
## Image stocks
- [7418_blocks_color_modules_rgb_square_icon](https://www.iconfinder.com/icons/7418/blocks_color_modules_rgb_square_icon) (Icon File) - Sergio Sanchesz Lopez, Futurosoft
![(Screenshot 6) The Launcher for WelsonJS Application Packages](https://ics.catswords.net/screenshot6.png)
## Contact me
If you have any inquiries regarding this project or if you are interested in becoming a partner, please don't hesitate to contact us. Particularly, for those using this project for website quality improvement automation, technical support will be exclusively available to partners.
![(Screenshot 7) Microsoft Monaco Editor on WelsonJS Launcher](https://ics.catswords.net/screenshot7.png)
- abuse@catswords.net
- ActivityPub [@catswords_oss@catswords.social](https://catswords.social/@catswords_oss)
## Thanks to
* :heart: Artwork (Logo image): [@druidesse](https://github.com/druidesse)
* :heart: Artwork (Cover image): [@_bag0@x.com](https://x.com/_bag0)
* :heart: Special Contributors: [@hcho3](https://github.com/hcho3), :octocat: [GitHub Sponsors](https://github.com/sponsors/gnh1201)
* :sunglasses: Heavy-industry specialized CSP(Cloud Service Provider) in Republic of Korea - Use case development
* :sunglasses: Live-commerce specialized online advertisement companies in Republic of Korea - Use case development
* :sunglasses: Information security companies in Republic of Korea - Use case development
* :sunglasses: Travel planning(e.g., Airlines, Hotels, Ticketing) related companies - Use case development
* :eyes: [Facebook Group "Javascript Programming"(javascript4u)](https://www.facebook.com/javascript4u/posts/build-a-windows-desktop-apps-with-javascript-html-and-cssmorioh-javascript-html-/1484014618472735/)
* :eyes: [morioh.com](https://morioh.com/a/23c427a82bf1/build-a-windows-desktop-apps-with-javascript-html-and-css)
* :eyes: CSDN
* :eyes: Qiita - Knowledge-base about WSH environment
* :sunglasses: Redsky Software - PoC(Proof of Concept) of the CommonJS on WSH environment
* :sunglasses: Inspired by a small-sized JavaScript payload demonstrated by a cybersecurity related group.
* :sunglasses: Inspired by the use of Named Shared Memory in a cross-runtime IPC implementation written by the unidentified developer.
* :eyes: Fediverse
* :eyes: [Hacker News](https://news.ycombinator.com/item?id=41316782)
* :eyes: [WebToolsWeekly](https://webtoolsweekly.com/archives/issue-585/)
* :eyes: [GeekNews](https://news.hada.io/weekly/202441) in GeekNews Weekly (2024-09-30 ~ 2024-10-06)
* :eyes: [daily.dev](https://app.daily.dev/posts/js-libraries-svg-tools-json-databases-8quregz3a)
* :eyes: [PitchHut](https://www.pitchhut.com/project/proj_Ya136OLSW5at)
* :eyes: [Disquiet](https://dis.qa/nv6T6)
* :eyes: [Node Weekly](https://nodeweekly.com/issues/582)
* :eyes: [Zhouexin (周e信)](https://www.zhouexin.com/issues/321)
## Report abuse
* [GitHub Security Advisories (gnh1201/welsonjs)](https://github.com/gnh1201/welsonjs/security)
* [abuse@catswords.net](mailto:abuse@catswords.net)
## Join the community
I am always open. Collaboration, opportunities, and community activities are all welcome.
* ActivityPub [@catswords_oss@catswords.social](https://catswords.social/@catswords_oss)
* XMPP [catswords@conference.omemo.id](xmpp:catswords@conference.omemo.id?join)
* [Join Catswords OSS on Microsoft Teams (teams.live.com)](https://teams.live.com/l/community/FEACHncAhq8ldnojAI)
* [Join Catswords OSS #welsonjs on Discord (discord.gg)](https://discord.gg/XKG5CjtXEj)
## Special channels
* [A paid consultation channel (m.expert.naver.com)](https://m.expert.naver.com/mobile/expert/product/detail?storeId=100051156&productId=100144540) is available for Korean<sup>(한국어)</sup> region.
* [Join the private operations channel (forms.gle)](https://forms.gle/ZKAAaGTiGamksHoo8) is available for all regions.
## License
[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Fgnh1201%2Fwelsonjs.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Fgnh1201%2Fwelsonjs?ref=badge_large)

20
REGASM.MD Normal file
View File

@ -0,0 +1,20 @@
# REGASM for WelsonJS
In general, the location of REGASM is as follows.
```
C:\Windows\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe
```
Or it may vary depending on the version.
## How to register .NET COM/DLL component
Example:
```
C:\Windows\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe /codebase WelsonJS.Toolkit.dll
C:\Windows\Microsoft.NET\Framework64\v2.0.50727\RegAsm.exe /codebase WelsonJS.Toolkit.dll
```
Thank you.

View File

@ -1,63 +1,38 @@
# Security Note for WelsonJS
## License
The WelsonJS project is available under either the GPLv3 or MS-RL opensource licenses. If the GPLv3 license is not compatible with Microsoft products, the MS-RL license applies; otherwise, the GPLv3 license is used. Under these licenses, if you distribute modified versions of this project's source code to third parties, you may be required to disclose the source code. For more details, please refer to the `LICENSE` and `LICENSE_MSRL` files.
## Caution
This repository contains information on accessing Windows APIs and functions in the JavaScript runtime, along with recent case studies. While this can provide a flexible development environment for anyone, it can also be misused for malicious purposes. Please be aware that using this project to create abuse tools, such as for DoS attacks, may result in legal consequences in your country. We encourage you to use this project only for creating web technology-based applications, like Electron, or legally permitted testing tools.
This repository contains information on accessing Windows APIs and functions on the JavaScript runtime, along with recent case studies. While this can provide a flexible development environment for anyone, it can also be misused for malicious purposes. Please be aware that using this project to create abuse tools, such as a DoS attack, may result in legal punishment in your country. We encourage you to use this project only for creating web technology-based applications, like Electron, or legally permitted testing tools.
## Known Use Cases
## Known use cases
WelsonJS is typically used for the following purposes:
* Testing web accessibility and compliance, including adherence to W3C standards (WEB-ARIA, WCAG), national laws (ADA/DDA, GDPR), and other relevant regulations.
* Exploring vulnerabilities of equipment within the local network.
* Improving the availability of VPN or proxy clients.
* Building automation, CI/CD (Continuous Integration/Continuous Delivery), DevOps, and SecOps.
* Asset evaluation (e.g., obtaining purchase history from online shopping and delivery websites).
* Online video streaming quality testing and improvement.
* Office automation and integration with LLM-based AI (e.g., ChatGPT) services.
* Testing web accessibility and compliance, including adherence to W3C standards (WEB-ARIA, WCAG), national laws (ADA/DDA, GDPR), and other relevant regulations.
* Exploring vulnerabilities of equipment within the local network.
* Improving the availability of VPN or Proxy clients.
* Building automation, CD/CI (Continuous Integration/Continuous Delivery), DevOps, and SecOps.
* Asset evaluation (e.g. Get a purchase history from online shopping and delivery websites)
* Online video streaming quality testing and improvement.
## Notes
1. If you plan to use WelsonJS for a purpose other than those mentioned above, please contact us beforehand.
2. If you are looking for ways to use WelsonJS more efficiently, referencing the [LOLBAS (Living Off The Land Binaries and Scripts)](https://lolbas-project.github.io/) list can be helpful.
1. If you plan to use WelsonJS for a purpose other than those mentioned above, please contact us beforehand.
2. If you are looking for ways to use WelsonJS more efficiently, referencing the [LOLBAS (Living Off The Land Binaries and Scripts)](https://lolbas-project.github.io/) list can be helpful.
## Guidelines
### Use of Online Shopping and Delivery Websites
We are aware of cases where WelsonJS has been used to access the websites of online shopping or delivery companies for asset valuation. This is a good use case, but there have been reports of website downtime caused by excessive concurrent requests. Please exercise caution and avoid excessive simultaneous executions.
### For the use of online shopping and delivery websites
We are aware of cases where WelsonJS has been used for asset valuation to access websites of online shopping or delivery companies. This is a good use case, but there have been reports of website downtime caused by excessive concurrent requests. Please exercise caution and avoid excessive simultaneous executions.
### Use for Online Video Streaming Quality Testing and Improvement
We are aware of cases where WelsonJS is used for video streaming quality testing and improvement. It should be used solely for expert-level streaming quality testing, often referred to by terms like 4K, 8K, HD, FHD, UHD, 720p, 1080p, etc. For such purposes, it is recommended to use videos provided by television manufacturers (e.g., LG, Samsung) or graphics card manufacturers (e.g., NVIDIA, AMD) specifically for testing purposes. It is essential to avoid using videos that contain content not legally permitted in your region. The WelsonJS developers and maintainers take no responsibility for the use of videos containing illegal content.
### For the use of online video streaming quality testing and improvement
We are aware of cases where WelsonJS is used for the purpose of video streaming quality testing and improvement. It should be used solely for expert-level streaming quality testing, often referred to by terms like 4K, 8K, HD, FHD, UHD, 720p, 1080p, etc. For such purposes, it is recommended to use videos provided by television manufacturers (e.g., LG, Samsung) or graphics card manufacturers (e.g., NVIDIA, AMD) specifically for testing purposes. It is essential to avoid using videos that contain content not legally permitted in the region. The WelsonJS developers and maintainers take no responsibility for the use of videos containing illegal content.
### Use for Scientific Research Institutes
WelsonJS is designed for flexible industrial facility control (a.k.a. Industrial Scripting) in environments where modifying compiled binaries is restricted. Parts or all of this project's source code may be found in use within scientific research institutes. In such cases, appropriate safety measures tailored to the specific application area may be required. If support is needed for these applications, please do not hesitate to contact us.
### Use for Security Testing
### For the use of security testing
We are aware of instances where WelsonJS has been used by legitimate cybersecurity firms to discover and test vulnerabilities (such as credential stuffing) in IoT devices. If you intend to use WelsonJS as a security testing tool, it should be done in a controlled environment that complies with legal regulations.
### Use for Cloud Monitoring
WelsonJS is a project inspired by the requirements of a cloud service provider to develop lightweight software (e.g., agents) for collecting metrics on Windows systems. While using WelsonJS for this purpose is desirable, ensuring security in the server-client communication is entirely the responsibility of the user.
## Alternative Names
This program is also known by the following names. These names are used solely for the purpose of identifying the work and do not impact the license:
* DOI [10.5281/zenodo.11382384](https://zenodo.org/doi/10.5281/zenodo.11382384)(2024) (CERN/OpenAIRE Zenodo)
* ["284757291"](https://ics.catswords.net/1494315-Certificate%2BSoR-284757291.pdf)(2024) (Registered with the [UK Copyright Service](https://copyrightservice.co.uk/))
* ["A0562"](https://www.oss.kr/dev_competition_activities/show/544723e6-850a-4956-9194-79640420c19a)(2023) (2023 Open-source Development Contest, NIPA National IT Industry Promotion Agency<sup>(정보통신산업진흥원)</sup>, Republic of Korea)
* ["2025-02-08-1952"](https://ics.catswords.net/20250410092300005.pdf)(2025) (Technical Data Bailment System (Technology Escrow), "Korea Foundation for Cooperation of Large & Small Business, Rural Affairs"<sup>(대·중소기업·농어업협력재단)</sup>, Republic of Korea)
* "C-2021-000237"(2021) (Copyright Registration Online System, Korea Copyright Commission<sup>(한국저작권위원회)</sup>, Republic of Korea)
* "Codename Macadamia"(2020) (Heavy industry specialized CSP in the Republic of Korea)
### For the use of cloud monitoring
WelsonJS is a project initiated by a cloud service provider in response to a request to develop a lightweight software (e.g., agent) for collecting metrics on Windows systems. While using WelsonJS for this purpose is desirable, ensuring security in the server-client communication is entirely the responsibility of the user.
## Report abuse
* [GitHub Security Advisories](https://github.com/gnh1201/welsonjs/security)
* [abuse@catswords.net](mailto:abuse@catswords.net)
If you discover any instances of this project being misused, please report them.
## Join the community
* ActivityPub [@catswords_oss@catswords.social](https://catswords.social/@catswords_oss)
* XMPP [catswords@conference.omemo.id](xmpp:catswords@conference.omemo.id?join)
* [Join Catswords OSS on Microsoft Teams (teams.live.com)](https://teams.live.com/l/community/FEACHncAhq8ldnojAI)
* [Join Catswords OSS #welsonjs on Discord (discord.gg)](https://discord.gg/XKG5CjtXEj)
## Special channels
* [A paid consultation channel (m.expert.naver.com)](https://m.expert.naver.com/mobile/expert/product/detail?storeId=100051156&productId=100144540) is available for Korean<sup>(한국어)</sup> region.
* [Join the private operations channel (forms.gle)](https://forms.gle/ZKAAaGTiGamksHoo8) is available for all regions.
* abuse@catswords.net
* ActivityPub [@catswords_oss@catswords.social](https://catswords.social/@catswords_oss)

BIN
WelsonJS.Toolkit.dll Normal file

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -1,64 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="ApiConstants.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
/// <summary>
/// Constants for the ESENT API. These don't have to be looked up via
/// system parameters.
/// </summary>
public static partial class SystemParameters
{
/// <summary>
/// The length of the prefix used to name files used by the database
/// engine.
/// </summary>
public const int BaseNameLength = 3;
/// <summary>
/// Maximum size of a table/column/index name.
/// </summary>
public const int NameMost = 64;
/// <summary>
/// Maximum size for columns which are not JET_coltyp.LongBinary
/// or JET_coltyp.LongText.
/// </summary>
public const int ColumnMost = 255;
/// <summary>
/// Maximum number of columns allowed in a table.
/// </summary>
public const int ColumnsMost = 65248;
/// <summary>
/// Maximum number of fixed columns allowed in a table.
/// </summary>
public const int ColumnsFixedMost = 127;
/// <summary>
/// Maximum number of variable-length columns allowed
/// in a table.
/// </summary>
public const int ColumnsVarMost = 128;
/// <summary>
/// Maximum number of tagged columns allowed in a table.
/// </summary>
public const int ColumnsTaggedMost = 64993;
/// <summary>
/// The number of pages that gives the smallest possible
/// temporary database.
/// </summary>
public const int PageTempDBSmallest = 14;
/// <summary>
/// The maximum length of a locale name (LOCALE_NAME_MAX_LENGTH from winnt.h).
/// </summary>
public const int LocaleNameMaxLength = 85;
}
}

View File

@ -1,96 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="BoolColumnValue.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
/// <summary>
/// A <see cref="bool"/> column value.
/// </summary>
public class BoolColumnValue : ColumnValueOfStruct<bool>
{
/// <summary>
/// A boxed true value that can be used by ValueAsObject.
/// </summary>
private static readonly object BoxedTrue = true;
/// <summary>
/// A boxed false value that can be used by ValueAsObject.
/// </summary>
private static readonly object BoxedFalse = false;
/// <summary>
/// Gets the last set or retrieved value of the column. The
/// value is returned as a generic object.
/// </summary>
public override object ValueAsObject
{
get
{
if (!this.Value.HasValue)
{
return null;
}
return this.Value.Value ? BoxedTrue : BoxedFalse;
}
}
/// <summary>
/// Gets the size of the value in the column. This returns 0 for
/// variable sized columns (i.e. binary and string).
/// </summary>
protected override int Size
{
[DebuggerStepThrough]
get { return sizeof(bool); }
}
/// <summary>
/// Recursive SetColumns method for data pinning. This populates the buffer and
/// calls the inherited SetColumns method.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to set the columns in. An update should be prepared.
/// </param>
/// <param name="columnValues">
/// Column values to set.
/// </param>
/// <param name="nativeColumns">
/// Structures to put the pinned data in.
/// </param>
/// <param name="i">Offset of this object in the array.</param>
/// <returns>An error code.</returns>
internal override unsafe int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i)
{
byte data = this.Value.GetValueOrDefault() ? (byte)0xFF : (byte)0x00;
return this.SetColumns(sesid, tableid, columnValues, nativeColumns, i, &data, sizeof(byte), this.Value.HasValue);
}
/// <summary>
/// Given data retrieved from ESENT, decode the data and set the value in the ColumnValue object.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within the bytes.</param>
/// <param name="count">The number of bytes to decode.</param>
/// <param name="err">The error returned from ESENT.</param>
protected override void GetValueFromBytes(byte[] value, int startIndex, int count, int err)
{
if (JET_wrn.ColumnNull == (JET_wrn)err)
{
this.Value = null;
}
else
{
this.CheckDataCount(count);
this.Value = BitConverter.ToBoolean(value, startIndex);
}
}
}
}

View File

@ -1,51 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="BoxedValueCache.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
/// <summary>
/// A cache for boxed values.
/// </summary>
/// <typeparam name="T">The type of object to cache.</typeparam>
internal static class BoxedValueCache<T> where T : struct, IEquatable<T>
{
/// <summary>
/// Number of boxed values to cache.
/// </summary>
private const int NumCachedBoxedValues = 257;
/// <summary>
/// Cached boxed values.
/// </summary>
private static readonly object[] BoxedValues = new object[NumCachedBoxedValues];
/// <summary>
/// Gets a boxed version of the value. A cached copy is used if possible.
/// </summary>
/// <param name="value">The value to box.</param>
/// <returns>A boxed version of the value.</returns>
public static object GetBoxedValue(T? value)
{
if (!value.HasValue)
{
return null;
}
T valueToBox = value.Value;
int index = (valueToBox.GetHashCode() & 0x7fffffff) % NumCachedBoxedValues;
object boxedValue = BoxedValues[index];
if (null == boxedValue || !((T)boxedValue).Equals(valueToBox))
{
boxedValue = valueToBox;
BoxedValues[index] = boxedValue;
}
return boxedValue;
}
}
}

View File

@ -1,68 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="ByteColumnValue.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System.Diagnostics;
/// <summary>
/// A <see cref="byte"/> column value.
/// </summary>
public class ByteColumnValue : ColumnValueOfStruct<byte>
{
/// <summary>
/// Gets the size of the value in the column. This returns 0 for
/// variable sized columns (i.e. binary and string).
/// </summary>
protected override int Size
{
[DebuggerStepThrough]
get { return sizeof(byte); }
}
/// <summary>
/// Recursive SetColumns method for data pinning. This populates the buffer and
/// calls the inherited SetColumns method.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to set the columns in. An update should be prepared.
/// </param>
/// <param name="columnValues">
/// Column values to set.
/// </param>
/// <param name="nativeColumns">
/// Structures to put the pinned data in.
/// </param>
/// <param name="i">Offset of this object in the array.</param>
/// <returns>An error code.</returns>
internal override unsafe int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i)
{
var data = this.Value.GetValueOrDefault();
return this.SetColumns(sesid, tableid, columnValues, nativeColumns, i, &data, sizeof(byte), this.Value.HasValue);
}
/// <summary>
/// Given data retrieved from ESENT, decode the data and set the value in the ColumnValue object.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within the bytes.</param>
/// <param name="count">The number of bytes to decode.</param>
/// <param name="err">The error returned from ESENT.</param>
protected override void GetValueFromBytes(byte[] value, int startIndex, int count, int err)
{
if (JET_wrn.ColumnNull == (JET_wrn)err)
{
this.Value = null;
}
else
{
this.CheckDataCount(count);
this.Value = value[startIndex];
}
}
}
}

View File

@ -1,136 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="BytesColumnValue.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
/// <summary>
/// A byte array column value.
/// </summary>
public class BytesColumnValue : ColumnValue
{
/// <summary>
/// Internal value.
/// </summary>
private byte[] internalValue;
/// <summary>
/// Gets the last set or retrieved value of the column. The
/// value is returned as a generic object.
/// </summary>
public override object ValueAsObject
{
[DebuggerStepThrough]
get { return this.Value; }
}
/// <summary>
/// Gets or sets the value of the column. Use <see cref="Api.SetColumns"/> to update a
/// record with the column value.
/// </summary>
public byte[] Value
{
get
{
return this.internalValue;
}
set
{
this.internalValue = value;
this.Error = value == null ? JET_wrn.ColumnNull : JET_wrn.Success;
}
}
/// <summary>
/// Gets the byte length of a column value, which is zero if column is null, otherwise
/// matches the actual length of the byte array.
/// </summary>
public override int Length
{
get { return this.Value != null ? this.Value.Length : 0; }
}
/// <summary>
/// Gets the size of the value in the column. This returns 0 for
/// variable sized columns (i.e. binary and string).
/// </summary>
protected override int Size
{
[DebuggerStepThrough]
get { return 0; }
}
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="BytesColumnValue"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="BytesColumnValue"/>.
/// </returns>
public override string ToString()
{
if (null == this.Value)
{
return string.Empty;
}
return BitConverter.ToString(this.Value, 0, Math.Min(this.Value.Length, 16));
}
/// <summary>
/// Recursive SetColumns method for data pinning. This populates the buffer and
/// calls the inherited SetColumns method.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to set the columns in. An update should be prepared.
/// </param>
/// <param name="columnValues">
/// Column values to set.
/// </param>
/// <param name="nativeColumns">
/// Structures to put the pinned data in.
/// </param>
/// <param name="i">Offset of this object in the array.</param>
/// <returns>An error code.</returns>
internal override unsafe int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i)
{
if (null != this.Value)
{
fixed (void* buffer = this.Value)
{
return this.SetColumns(
sesid, tableid, columnValues, nativeColumns, i, buffer, this.Value.Length, true);
}
}
return this.SetColumns(sesid, tableid, columnValues, nativeColumns, i, null, 0, false);
}
/// <summary>
/// Given data retrieved from ESENT, decode the data and set the value in the ColumnValue object.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within the bytes.</param>
/// <param name="count">The number of bytes to decode.</param>
/// <param name="err">The error returned from ESENT.</param>
protected override void GetValueFromBytes(byte[] value, int startIndex, int count, int err)
{
if (JET_wrn.ColumnNull == (JET_wrn)err)
{
this.Value = null;
}
else
{
var copiedValue = new byte[count];
Buffer.BlockCopy(value, startIndex, copiedValue, 0, count);
this.Value = copiedValue;
}
}
}
}

View File

@ -1,79 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="Caches.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System.Diagnostics;
/// <summary>
/// Static class containing MemoryCaches for different ESENT buffers.
/// Use these to avoid memory allocations when the memory will be
/// used for a brief time.
/// </summary>
internal static class Caches
{
/// <summary>
/// The maximum key size that any version of ESENT can have for
/// any page size. This is also the maximum bookmark size.
/// </summary>
private const int KeyMostMost = 2000;
/// <summary>
/// Reserve 1 extra space for keys made with prefix or wildcard.
/// </summary>
private const int LimitKeyMostMost = KeyMostMost + 1;
/// <summary>
/// The maximum number of buffers we want in a cache.
/// </summary>
private const int MaxBuffers = 16;
/// <summary>
/// Cached buffers for columns.
/// </summary>
private static readonly MemoryCache TheColumnCache = new MemoryCache(128 * 1024, MaxBuffers);
/// <summary>
/// Cached buffers for keys and bookmarks.
/// </summary>
private static readonly MemoryCache TheBookmarkCache = new MemoryCache(LimitKeyMostMost, MaxBuffers);
/// <summary>
/// Cached buffers for keys and bookmarks.
/// </summary>
private static readonly MemoryCache TheSecondaryBookmarkCache = new MemoryCache(LimitKeyMostMost, MaxBuffers);
/// <summary>
/// Gets the cached buffers for columns.
/// </summary>
public static MemoryCache ColumnCache
{
[DebuggerStepThrough]
get { return TheColumnCache; }
}
/// <summary>
/// Gets the cached buffers for keys and bookmarks.
/// </summary>
public static MemoryCache BookmarkCache
{
[DebuggerStepThrough]
get { return TheBookmarkCache; }
}
/// <summary>
/// Gets the cached buffers for keys and secondary bookmarks.
/// </summary>
public static MemoryCache SecondaryBookmarkCache
{
[DebuggerStepThrough]
get
{
return TheSecondaryBookmarkCache;
}
}
}
}

View File

@ -1,98 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="CallbackWrappers.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System.Collections.Generic;
/// <summary>
/// <para>
/// A collection of wrapped callbacks. This is used when the wrapped callback
/// can be garbage collected. The wrappers should be removed from the collection
/// when the callback is collected.
/// </para>
/// <para>
/// Removing the wrappers can lead to crashes. In this case we trust
/// the client code to keep its callback alive until ESENT doesn't need it any
/// more. Once the wrapped callback is garbage collected we allow the wrapper
/// to be collected as well. If ESENT subsequently uses the callback there will
/// be a crash.
/// </para>
/// <para>
/// The reason this is hard to deal with is that the lifetime of a JET_CALLBACK
/// isn't very clear. Table callbacks can stick around until the table meta-data
/// is purged, while a JetDefragment callback can be used until defrag ends. On
/// the other hand, keeping the callback wrapper alive indefinitely would lead
/// to unbounded memory use.
/// </para>
/// </summary>
internal sealed class CallbackWrappers
{
/// <summary>
/// Used to synchronize access to this object.
/// </summary>
private readonly object lockObject = new object();
/// <summary>
/// A list of the wrapped callbacks.
/// </summary>
private readonly List<JetCallbackWrapper> callbackWrappers = new List<JetCallbackWrapper>();
/// <summary>
/// Wrap a callback and returns its wrapper. If the callback is
/// already wrapped then the existing wrapper is returned.
/// </summary>
/// <param name="callback">The callback to add.</param>
/// <returns>The callback wrapper for the callback.</returns>
public JetCallbackWrapper Add(JET_CALLBACK callback)
{
lock (this.lockObject)
{
JetCallbackWrapper wrapper;
if (!this.TryFindWrapperFor(callback, out wrapper))
{
wrapper = new JetCallbackWrapper(callback);
this.callbackWrappers.Add(wrapper);
}
return wrapper;
}
}
/// <summary>
/// Go through the collection of callback wrappers and remove any dead callbacks.
/// </summary>
public void Collect()
{
lock (this.lockObject)
{
this.callbackWrappers.RemoveAll(wrapper => !wrapper.IsAlive);
}
}
/// <summary>
/// Look in the list of callback wrappers to see if there is already an entry for
/// this callback.
/// </summary>
/// <param name="callback">The callback to look for.</param>
/// <param name="wrapper">Returns the wrapper, if found.</param>
/// <returns>True if a wrapper was found, false otherwise.</returns>
private bool TryFindWrapperFor(JET_CALLBACK callback, out JetCallbackWrapper wrapper)
{
foreach (JetCallbackWrapper w in this.callbackWrappers)
{
if (w.IsWrapping(callback))
{
wrapper = w;
return true;
}
}
wrapper = null;
return false;
}
}
}

View File

@ -1,101 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="ColumnInfo.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
/// <summary>
/// Information about one Esent column. This is not an interop
/// class, but is used by the meta-data helper methods.
/// </summary>
public sealed class ColumnInfo
{
/// <summary>
/// The default value of the column.
/// </summary>
private readonly ReadOnlyCollection<byte> defaultValue;
/// <summary>
/// Initializes a new instance of the ColumnInfo class.
/// </summary>
/// <param name="name">Name of the column.</param>
/// <param name="columnid">ID of the column.</param>
/// <param name="coltyp">Type of the column.</param>
/// <param name="cp">Codepage of the column.</param>
/// <param name="maxLength">Maximum length of the column.</param>
/// <param name="defaultValue">Column default value.</param>
/// <param name="grbit">Column option.</param>
internal ColumnInfo(
string name,
JET_COLUMNID columnid,
JET_coltyp coltyp,
JET_CP cp,
int maxLength,
byte[] defaultValue,
ColumndefGrbit grbit)
{
this.Name = name;
this.Columnid = columnid;
this.Coltyp = coltyp;
this.Cp = cp;
this.MaxLength = maxLength;
this.defaultValue = (null == defaultValue) ? null : new ReadOnlyCollection<byte>(defaultValue);
this.Grbit = grbit;
}
/// <summary>
/// Gets the name of the column.
/// </summary>
public string Name { get; private set; }
/// <summary>
/// Gets the ID of the column.
/// </summary>
public JET_COLUMNID Columnid { get; private set; }
/// <summary>
/// Gets the type of the column.
/// </summary>
public JET_coltyp Coltyp { get; private set; }
/// <summary>
/// Gets the code page of the column.
/// </summary>
public JET_CP Cp { get; private set; }
/// <summary>
/// Gets the maximum length of the column.
/// </summary>
public int MaxLength { get; private set; }
/// <summary>
/// Gets the default value of the column.
/// </summary>
public IList<byte> DefaultValue
{
get { return this.defaultValue; }
}
/// <summary>
/// Gets the column options.
/// </summary>
public ColumndefGrbit Grbit { get; private set; }
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="ColumnInfo"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="ColumnInfo"/>.
/// </returns>
public override string ToString()
{
return this.Name;
}
}
}

View File

@ -1,78 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="ColumnInfoEnumerator.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System.Text;
using Microsoft.Isam.Esent.Interop.Implementation;
/// <summary>
/// Base class for enumerators that return ColumnInfo objects. Subclasses differ
/// by how they open the table.
/// </summary>
internal abstract class ColumnInfoEnumerator : TableEnumerator<ColumnInfo>
{
/// <summary>
/// Initializes a new instance of the <see cref="ColumnInfoEnumerator"/> class.
/// </summary>
/// <param name="sesid">
/// The session to use.
/// </param>
protected ColumnInfoEnumerator(JET_SESID sesid) : base(sesid)
{
}
/// <summary>
/// Gets or sets the columnlist used to retrieve data.
/// </summary>
protected JET_COLUMNLIST Columnlist { get; set; }
/// <summary>
/// Gets the entry the cursor is currently positioned on.
/// </summary>
/// <returns>The entry the cursor is currently positioned on.</returns>
protected override ColumnInfo GetCurrent()
{
return GetColumnInfoFromColumnlist(this.Sesid, this.Columnlist);
}
/// <summary>
/// Create a ColumnInfo object from the data in the current JET_COLUMNLIST entry.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="columnlist">The columnlist to take the data from.</param>
/// <returns>A ColumnInfo object containing the information from that record.</returns>
private static ColumnInfo GetColumnInfoFromColumnlist(JET_SESID sesid, JET_COLUMNLIST columnlist)
{
// As of Sep 2015, JetGetColumnInfoW is only called for Win8+. Even though Unicode should have
// worked in Win7, it wasn't reliable until Win8.
Encoding encodingOfTextColumns = EsentVersion.SupportsWindows8Features ? Encoding.Unicode : LibraryHelpers.EncodingASCII;
string name = Api.RetrieveColumnAsString(
sesid,
columnlist.tableid,
columnlist.columnidcolumnname,
encodingOfTextColumns,
RetrieveColumnGrbit.None);
name = StringCache.TryToIntern(name);
var columnidValue = (uint)Api.RetrieveColumnAsUInt32(sesid, columnlist.tableid, columnlist.columnidcolumnid);
var coltypValue = (uint)Api.RetrieveColumnAsUInt32(sesid, columnlist.tableid, columnlist.columnidcoltyp);
uint codepageValue = (ushort)Api.RetrieveColumnAsUInt16(sesid, columnlist.tableid, columnlist.columnidCp);
var maxLength = (uint)Api.RetrieveColumnAsUInt32(sesid, columnlist.tableid, columnlist.columnidcbMax);
byte[] defaultValue = Api.RetrieveColumn(sesid, columnlist.tableid, columnlist.columnidDefault);
var grbitValue = (uint)Api.RetrieveColumnAsUInt32(sesid, columnlist.tableid, columnlist.columnidgrbit);
return new ColumnInfo(
name,
new JET_COLUMNID { Value = columnidValue },
(JET_coltyp)coltypValue,
(JET_CP)codepageValue,
unchecked((int)maxLength),
defaultValue,
(ColumndefGrbit)grbitValue);
}
}
}

View File

@ -1,357 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="ColumnStream.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.IO;
/// <summary>
/// This class provides a streaming interface to a long-value column
/// (i.e. a column of type <see cref="JET_coltyp.LongBinary"/> or
/// <see cref="JET_coltyp.LongText"/>).
/// </summary>
[SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules",
"SA1305:FieldNamesMustNotUseHungarianNotation",
Justification = "This should match the unmanaged API, which isn't capitalized.")]
public class ColumnStream : Stream
{
/// <summary>
/// The size of the biggest long-value column ESENT supports.
/// </summary>
private const int MaxLongValueSize = 0x7fffffff;
/// <summary>
/// Session to use.
/// </summary>
private readonly JET_SESID sesid;
/// <summary>
/// Cursor to use.
/// </summary>
private readonly JET_TABLEID tableid;
/// <summary>
/// Columnid to use.
/// </summary>
private readonly JET_COLUMNID columnid;
/// <summary>
/// Current LV offset.
/// </summary>
private int ibLongValue;
/// <summary>
/// Initializes a new instance of the ColumnStream class.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to use.</param>
/// <param name="columnid">The columnid of the column to set/retrieve data from.</param>
public ColumnStream(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid)
{
// In some cases we rely on Int32 arithmetic overflow checking to catch
// errors, which assumes that a long-value can store Int32.MaxValue bytes.
Debug.Assert(MaxLongValueSize == int.MaxValue, "Expected maximum long value size to be Int32.MaxValue");
this.sesid = sesid;
this.tableid = tableid;
this.columnid = columnid;
this.Itag = 1;
}
/// <summary>
/// Gets or sets the itag of the column.
/// </summary>
public int Itag { get; set; }
/// <summary>
/// Gets a value indicating whether the stream supports reading.
/// </summary>
public override bool CanRead
{
[DebuggerStepThrough]
get { return true; }
}
/// <summary>
/// Gets a value indicating whether the stream supports writing.
/// </summary>
public override bool CanWrite
{
[DebuggerStepThrough]
get { return true; }
}
/// <summary>
/// Gets a value indicating whether the stream supports seeking.
/// </summary>
public override bool CanSeek
{
[DebuggerStepThrough]
get { return true; }
}
/// <summary>
/// Gets or sets the current position in the stream.
/// </summary>
public override long Position
{
[DebuggerStepThrough]
get
{
return this.ibLongValue;
}
set
{
if (value < 0 || value > MaxLongValueSize)
{
throw new ArgumentOutOfRangeException("value", value, "A long-value offset has to be between 0 and 0x7fffffff bytes");
}
this.ibLongValue = checked((int)value);
}
}
/// <summary>
/// Gets the current length of the stream.
/// </summary>
public override long Length
{
get
{
int size;
var retinfo = new JET_RETINFO { itagSequence = this.Itag, ibLongValue = 0 };
Api.JetRetrieveColumn(this.sesid, this.tableid, this.columnid, null, 0, out size, RetrieveGrbit, retinfo);
return size;
}
}
/// <summary>
/// Gets the options that should be used with JetRetrieveColumn.
/// </summary>
private static RetrieveColumnGrbit RetrieveGrbit
{
[DebuggerStepThrough]
get
{
// Always use the RetrieveCopy options. This makes the ColumnStream work
// well when setting a column. If we don't always use RetrieveCopy then
// things like seeking from the end of a column might not work properly.
return RetrieveColumnGrbit.RetrieveCopy;
}
}
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="ColumnStream"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="ColumnStream"/>.
/// </returns>
public override string ToString()
{
return string.Format(CultureInfo.InvariantCulture, "ColumnStream(0x{0:x}:{1})", this.columnid.Value, this.Itag);
}
/// <summary>
/// Flush the stream.
/// </summary>
public override void Flush()
{
// nothing is required
}
/// <summary>
/// Writes a sequence of bytes to the current stream and advances the current
/// position within this stream by the number of bytes written.
/// </summary>
/// <param name="buffer">The buffer to write from.</param>
/// <param name="offset">The offset in the buffer to write.</param>
/// <param name="count">The number of bytes to write.</param>
public override void Write(byte[] buffer, int offset, int count)
{
CheckBufferArguments(buffer, offset, count);
int length = checked((int)this.Length);
JET_SETINFO setinfo;
int newIbLongValue = checked(this.ibLongValue + count);
// If our current position is beyond the end of the LV extend
// the LV to the write point
if (this.ibLongValue > length)
{
setinfo = new JET_SETINFO { itagSequence = this.Itag };
Api.JetSetColumn(this.sesid, this.tableid, this.columnid, null, this.ibLongValue, SetColumnGrbit.SizeLV, setinfo);
length = this.ibLongValue;
}
SetColumnGrbit grbit;
if (this.ibLongValue == length)
{
grbit = SetColumnGrbit.AppendLV;
}
else if (newIbLongValue >= length)
{
grbit = SetColumnGrbit.OverwriteLV | SetColumnGrbit.SizeLV;
}
else
{
grbit = SetColumnGrbit.OverwriteLV;
}
setinfo = new JET_SETINFO { itagSequence = this.Itag, ibLongValue = this.ibLongValue };
Api.JetSetColumn(this.sesid, this.tableid, this.columnid, buffer, count, offset, grbit, setinfo);
checked
{
this.ibLongValue += count;
}
}
/// <summary>
/// Reads a sequence of bytes from the current stream and advances the
/// position within the stream by the number of bytes read.
/// </summary>
/// <param name="buffer">The buffer to read into.</param>
/// <param name="offset">The offset in the buffer to read into.</param>
/// <param name="count">The number of bytes to read.</param>
/// <returns>The number of bytes read into the buffer.</returns>
public override int Read(byte[] buffer, int offset, int count)
{
CheckBufferArguments(buffer, offset, count);
if (this.ibLongValue >= this.Length)
{
return 0;
}
int length;
var retinfo = new JET_RETINFO { itagSequence = this.Itag, ibLongValue = this.ibLongValue };
Api.JetRetrieveColumn(this.sesid, this.tableid, this.columnid, buffer, count, offset, out length, RetrieveGrbit, retinfo);
int bytesRead = Math.Min(length, count);
checked
{
this.ibLongValue += bytesRead;
}
return bytesRead;
}
/// <summary>
/// Sets the length of the stream.
/// </summary>
/// <param name="value">The desired length, in bytes.</param>
public override void SetLength(long value)
{
if (value > MaxLongValueSize || value < 0)
{
throw new ArgumentOutOfRangeException("value", value, "A LongValueStream cannot be longer than 0x7FFFFFF or less than 0 bytes");
}
if (value < this.Length && value > 0)
{
// BUG: Shrinking the column multiple times and then growing it can sometimes hit an unpleasant
// ESENT defect which causes a hang. To make sure we never have that problem we read out the data,
// and insert into a new long-value. This is not efficient.
var data = new byte[value];
var retinfo = new JET_RETINFO { itagSequence = this.Itag, ibLongValue = 0 };
int actualDataSize;
Api.JetRetrieveColumn(
this.sesid,
this.tableid,
this.columnid,
data,
data.Length,
out actualDataSize,
RetrieveGrbit,
retinfo);
var setinfo = new JET_SETINFO { itagSequence = this.Itag };
Api.JetSetColumn(this.sesid, this.tableid, this.columnid, data, data.Length, SetColumnGrbit.None, setinfo);
}
else
{
var setinfo = new JET_SETINFO { itagSequence = this.Itag };
SetColumnGrbit grbit = (0 == value) ? SetColumnGrbit.ZeroLength : SetColumnGrbit.SizeLV;
Api.JetSetColumn(this.sesid, this.tableid, this.columnid, null, checked((int)value), grbit, setinfo);
}
// Setting the length moves the offset back to the end of the data
if (this.ibLongValue > value)
{
this.ibLongValue = checked((int)value);
}
}
/// <summary>
/// Sets the position in the current stream.
/// </summary>
/// <param name="offset">Byte offset relative to the origin parameter.</param>
/// <param name="origin">A SeekOrigin indicating the reference point for the new position.</param>
/// <returns>The new position in the current stream.</returns>
public override long Seek(long offset, SeekOrigin origin)
{
long newOffset;
switch (origin)
{
case SeekOrigin.Begin:
newOffset = offset;
break;
case SeekOrigin.End:
newOffset = checked(this.Length + offset);
break;
case SeekOrigin.Current:
newOffset = checked(this.ibLongValue + offset);
break;
default:
throw new ArgumentOutOfRangeException("origin", origin, "Unknown origin");
}
if (newOffset < 0 || newOffset > MaxLongValueSize)
{
throw new ArgumentOutOfRangeException("offset", offset, "invalid offset/origin combination");
}
this.ibLongValue = checked((int)newOffset);
return this.ibLongValue;
}
/// <summary>
/// Check the buffer arguments given to Read/Write .
/// </summary>
/// <param name="buffer">The buffer.</param>
/// <param name="offset">The offset in the buffer to read/write to.</param>
/// <param name="count">The number of bytes to read/write.</param>
private static void CheckBufferArguments(ICollection<byte> buffer, int offset, int count)
{
if (null == buffer)
{
throw new ArgumentNullException("buffer");
}
if (offset < 0)
{
throw new ArgumentOutOfRangeException("offset", offset, "cannot be negative");
}
if (count < 0)
{
throw new ArgumentOutOfRangeException("count", count, "cannot be negative");
}
if (checked(buffer.Count - offset) < count)
{
throw new ArgumentOutOfRangeException("count", count, "cannot be larger than the size of the buffer");
}
}
}
}

View File

@ -1,382 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="ColumnValue.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
/// <summary>
/// Base class for objects that represent a column value to be set.
/// </summary>
public abstract partial class ColumnValue
{
/// <summary>
/// Internal grbit.
/// </summary>
private RetrieveColumnGrbit grbit;
/// <summary>
/// Initializes a new instance of the ColumnValue class.
/// </summary>
protected ColumnValue()
{
this.ItagSequence = 1;
}
/// <summary>
/// Gets or sets the columnid to be set or retrieved.
/// </summary>
public JET_COLUMNID Columnid { get; set; }
/// <summary>
/// Gets the last set or retrieved value of the column. The
/// value is returned as a generic object.
/// </summary>
public abstract object ValueAsObject { get; }
/// <summary>
/// Gets or sets column update options.
/// </summary>
public SetColumnGrbit SetGrbit { get; set; }
/// <summary>
/// Gets or sets column retrieval options.
/// </summary>
public RetrieveColumnGrbit RetrieveGrbit
{
get
{
return this.grbit;
}
set
{
this.ValidateRetrieveGrbit(value);
this.grbit = value;
}
}
/// <summary>
/// Gets or sets the column itag sequence.
/// </summary>
public int ItagSequence { get; set; }
/// <summary>
/// Gets the warning generated by retrieving or setting this column.
/// </summary>
public JET_wrn Error { get; internal set; }
/// <summary>
/// Gets the byte length of a column value, which is zero if column is null, otherwise
/// it matches the Size for fixed-size columns and represent the actual value byte
/// length for variable sized columns (i.e. binary and string). For strings the length
/// is determined in assumption two bytes per character.
/// </summary>
public abstract int Length { get; }
/// <summary>
/// Gets the size of the value in the column. This returns 0 for
/// variable sized columns (i.e. binary and string).
/// </summary>
protected abstract int Size { get; }
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="ColumnValue"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="ColumnValue"/>.
/// </returns>
public abstract override string ToString();
/// <summary>
/// Recursive RetrieveColumns method for data pinning. This should pin a buffer and
/// call the inherited RetrieveColumns method.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to retrieve the columns from.
/// </param>
/// <param name="columnValues">
/// Column values to retrieve.
/// </param>
internal static void RetrieveColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues)
{
const int MaxColumnValues = 1024;
if (columnValues.Length > MaxColumnValues)
{
throw new ArgumentOutOfRangeException("columnValues", columnValues.Length, "Too many column values");
}
unsafe
{
byte[] buffer = null;
NATIVE_RETRIEVECOLUMN* nativeRetrievecolumns = stackalloc NATIVE_RETRIEVECOLUMN[columnValues.Length];
try
{
buffer = Caches.ColumnCache.Allocate();
Debug.Assert(MaxColumnValues * 16 < buffer.Length, "Maximum size of fixed columns could exceed buffer size");
fixed (byte* pinnedBuffer = buffer)
{
byte* currentBuffer = pinnedBuffer;
int numVariableLengthColumns = columnValues.Length;
// First the fixed-size columns
for (int i = 0; i < columnValues.Length; ++i)
{
if (0 != columnValues[i].Size)
{
columnValues[i].MakeNativeRetrieveColumn(ref nativeRetrievecolumns[i]);
nativeRetrievecolumns[i].pvData = new IntPtr(currentBuffer);
nativeRetrievecolumns[i].cbData = checked((uint)columnValues[i].Size);
currentBuffer += nativeRetrievecolumns[i].cbData;
Debug.Assert(currentBuffer <= pinnedBuffer + buffer.Length, "Moved past end of pinned buffer");
numVariableLengthColumns--;
}
}
// Now the variable-length columns
if (numVariableLengthColumns > 0)
{
int bufferUsed = checked((int)(currentBuffer - pinnedBuffer));
int bufferRemaining = checked(buffer.Length - bufferUsed);
int bufferPerColumn = bufferRemaining / numVariableLengthColumns;
Debug.Assert(bufferPerColumn > 0, "Not enough buffer left to retrieve variable length columns");
// Now the variable-size columns
for (int i = 0; i < columnValues.Length; ++i)
{
if (0 == columnValues[i].Size)
{
columnValues[i].MakeNativeRetrieveColumn(ref nativeRetrievecolumns[i]);
nativeRetrievecolumns[i].pvData = new IntPtr(currentBuffer);
nativeRetrievecolumns[i].cbData = checked((uint)bufferPerColumn);
currentBuffer += nativeRetrievecolumns[i].cbData;
Debug.Assert(currentBuffer <= pinnedBuffer + buffer.Length, "Moved past end of pinned buffer");
}
}
}
// Retrieve the columns
Api.Check(Api.Impl.JetRetrieveColumns(sesid, tableid, nativeRetrievecolumns, columnValues.Length));
// Propagate the warnings and output.
for (int i = 0; i < columnValues.Length; ++i)
{
columnValues[i].Error = (JET_wrn)nativeRetrievecolumns[i].err;
columnValues[i].ItagSequence = (int)nativeRetrievecolumns[i].itagSequence;
}
// Now parse out the columns that were retrieved successfully
for (int i = 0; i < columnValues.Length; ++i)
{
if (nativeRetrievecolumns[i].err != (int)JET_wrn.BufferTruncated)
{
byte* columnBuffer = (byte*)nativeRetrievecolumns[i].pvData;
int startIndex = checked((int)(columnBuffer - pinnedBuffer));
columnValues[i].GetValueFromBytes(
buffer,
startIndex,
checked((int)nativeRetrievecolumns[i].cbActual),
nativeRetrievecolumns[i].err);
}
}
}
// Finally retrieve the buffers where the columns weren't large enough.
RetrieveTruncatedBuffers(sesid, tableid, columnValues, nativeRetrievecolumns);
}
finally
{
if (buffer != null)
{
Caches.ColumnCache.Free(ref buffer);
}
}
}
}
/// <summary>
/// Recursive SetColumns method for data pinning. This should populate the buffer and
/// call the inherited SetColumns method.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to set the columns in. An update should be prepared.
/// </param>
/// <param name="columnValues">
/// Column values to set.
/// </param>
/// <param name="nativeColumns">
/// Structures to put the pinned data in.
/// </param>
/// <param name="i">Offset of this object in the array.</param>
/// <returns>An error code.</returns>
internal abstract unsafe int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i);
/// <summary>
/// Recursive SetColumns function used to pin data.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to set the columns in. An update should be prepared.
/// </param>
/// <param name="columnValues">
/// Column values to set.
/// </param>
/// <param name="nativeColumns">
/// Structures to put the pinned data in.
/// </param>
/// <param name="i">Offset of this object in the array.</param>
/// <param name="buffer">The buffer for this object.</param>
/// <param name="bufferSize">Size of the buffer for ths object.</param>
/// <param name="hasValue">True if this object is non null.</param>
/// <returns>An error code.</returns>
/// <remarks>
/// This is marked as internal because it uses the NATIVE_SETCOLUMN type
/// which is also marked as internal. It should be treated as a protected
/// method though.
/// </remarks>
internal unsafe int SetColumns(
JET_SESID sesid,
JET_TABLEID tableid,
ColumnValue[] columnValues,
NATIVE_SETCOLUMN* nativeColumns,
int i,
void* buffer,
int bufferSize,
bool hasValue)
{
Debug.Assert(this == columnValues[i], "SetColumns should be called on the current object");
this.MakeNativeSetColumn(ref nativeColumns[i]);
if (hasValue)
{
nativeColumns[i].cbData = checked((uint)bufferSize);
nativeColumns[i].pvData = new IntPtr(buffer);
if (0 == bufferSize)
{
nativeColumns[i].grbit |= (uint)SetColumnGrbit.ZeroLength;
}
}
int err = i == columnValues.Length - 1
? Api.Impl.JetSetColumns(sesid, tableid, nativeColumns, columnValues.Length)
: columnValues[i + 1].SetColumns(sesid, tableid, columnValues, nativeColumns, i + 1);
this.Error = (JET_wrn)nativeColumns[i].err;
return err;
}
/// <summary>
/// Given data retrieved from ESENT, decode the data and set the value in the ColumnValue object.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within the bytes.</param>
/// <param name="count">The number of bytes to decode.</param>
/// <param name="err">The error returned from ESENT.</param>
protected abstract void GetValueFromBytes(byte[] value, int startIndex, int count, int err);
/// <summary>
/// Validation for the requested retrieve options for the column.
/// </summary>
/// <param name="grbit">The retrieve options to validate.</param>
protected virtual void ValidateRetrieveGrbit(RetrieveColumnGrbit grbit)
{
// We cannot support this request when there is no way to indicate that a column reference is returned.
if ((grbit & (RetrieveColumnGrbit)0x00020000) != 0) // UnpublishedGrbits.RetrieveAsRefIfNotInRecord
{
throw new EsentInvalidGrbitException();
}
}
/// <summary>
/// Retrieve the value for columns whose buffers were truncated.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The table to use.</param>
/// <param name="columnValues">The column values.</param>
/// <param name="nativeRetrievecolumns">
/// The native retrieve columns that match the column values.
/// </param>
private static unsafe void RetrieveTruncatedBuffers(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_RETRIEVECOLUMN* nativeRetrievecolumns)
{
for (int i = 0; i < columnValues.Length; ++i)
{
if (nativeRetrievecolumns[i].err == (int)JET_wrn.BufferTruncated)
{
var buffer = new byte[nativeRetrievecolumns[i].cbActual];
int actualSize;
int err;
var retinfo = new JET_RETINFO { itagSequence = columnValues[i].ItagSequence };
// Pin the buffer and retrieve the data
fixed (byte* pinnedBuffer = buffer)
{
err = Api.Impl.JetRetrieveColumn(
sesid,
tableid,
columnValues[i].Columnid,
new IntPtr(pinnedBuffer),
buffer.Length,
out actualSize,
columnValues[i].RetrieveGrbit,
retinfo);
}
if (JET_wrn.BufferTruncated == (JET_wrn)err)
{
string error = string.Format(
CultureInfo.CurrentCulture,
"Column size changed from {0} to {1}. The record was probably updated by another thread.",
buffer.Length,
actualSize);
Trace.TraceError(error);
throw new InvalidOperationException(error);
}
// Throw errors, but put warnings in the structure
Api.Check(err);
columnValues[i].Error = (JET_wrn)err;
// For BytesColumnValue this will copy the data to a new array.
// If this situation becomes common we should simply use the array.
columnValues[i].GetValueFromBytes(buffer, 0, actualSize, err);
}
}
}
/// <summary>
/// Create a native SetColumn from this object.
/// </summary>
/// <param name="setcolumn">The native setcolumn structure to fill in.</param>
private void MakeNativeSetColumn(ref NATIVE_SETCOLUMN setcolumn)
{
setcolumn.columnid = this.Columnid.Value;
setcolumn.grbit = (uint)this.SetGrbit;
setcolumn.itagSequence = checked((uint)this.ItagSequence);
}
/// <summary>
/// Create a native RetrieveColumn from this object.
/// </summary>
/// <param name="retrievecolumn">
/// The retrieve column structure to fill in.
/// </param>
private void MakeNativeRetrieveColumn(ref NATIVE_RETRIEVECOLUMN retrievecolumn)
{
retrievecolumn.columnid = this.Columnid.Value;
retrievecolumn.grbit = (uint)this.RetrieveGrbit;
retrievecolumn.itagSequence = checked((uint)this.ItagSequence);
}
}
}

View File

@ -1,82 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="ColumnValueOfStruct.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
/// <summary>
/// Set a column of a struct type (e.g. <see cref="Int32"/>/<see cref="Guid"/>).
/// </summary>
/// <typeparam name="T">Type to set.</typeparam>
public abstract class ColumnValueOfStruct<T> : ColumnValue where T : struct, IEquatable<T>
{
/// <summary>
/// Internal value.
/// </summary>
private T? internalValue;
/// <summary>
/// Gets the last set or retrieved value of the column. The
/// value is returned as a generic object.
/// </summary>
public override object ValueAsObject
{
get
{
return BoxedValueCache<T>.GetBoxedValue(this.Value);
}
}
/// <summary>
/// Gets or sets the value in the struct.
/// </summary>
public T? Value
{
get
{
return this.internalValue;
}
set
{
this.internalValue = value;
this.Error = value == null ? JET_wrn.ColumnNull : JET_wrn.Success;
}
}
/// <summary>
/// Gets the byte length of a column value, which is zero if column is null, otherwise
/// it matches the Size for this fixed-size column.
/// </summary>
public override int Length
{
get { return this.Value.HasValue ? this.Size : 0; }
}
/// <summary>
/// Gets a string representation of this object.
/// </summary>
/// <returns>A string representation of this object.</returns>
public override string ToString()
{
return this.Value.ToString();
}
/// <summary>
/// Make sure the retrieved data is exactly the size needed for
/// the structure. An exception is thrown if there is a mismatch.
/// </summary>
/// <param name="count">The size of the retrieved data.</param>
protected void CheckDataCount(int count)
{
if (this.Size != count)
{
throw new EsentInvalidColumnException();
}
}
}
}

View File

@ -1,175 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="Conversions.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Collections.Generic;
using System.Globalization;
/// <summary>
/// Provide methods to convert data and flags between
/// Win32 and the .NET Framework.
/// </summary>
public static class Conversions
{
/// <summary>
/// Maps a CompareOption enumeration to the corresponding LCMapString flag.
/// </summary>
private static readonly IDictionary<CompareOptions, uint> CompareOptionsToLcmapFlags;
/// <summary>
/// Maps an LCMapString flag to the corresponding CompareOption enumeration.
/// </summary>
private static readonly IDictionary<uint, CompareOptions> LcmapFlagsToCompareOptions;
/// <summary>
/// Initializes static members of the Conversions class. This sets up the
/// conversion mapping dictionaries.
/// </summary>
static Conversions()
{
// Rather than creating both dictionaries, define one as the inverse of the other.
CompareOptionsToLcmapFlags = new Dictionary<CompareOptions, uint>
{
{ CompareOptions.IgnoreCase, NativeMethods.NORM_IGNORECASE },
{ CompareOptions.IgnoreKanaType, NativeMethods.NORM_IGNOREKANATYPE },
{ CompareOptions.IgnoreNonSpace, NativeMethods.NORM_IGNORENONSPACE },
{ CompareOptions.IgnoreSymbols, NativeMethods.NORM_IGNORESYMBOLS },
{ CompareOptions.IgnoreWidth, NativeMethods.NORM_IGNOREWIDTH },
{ CompareOptions.StringSort, NativeMethods.SORT_STRINGSORT }
};
LcmapFlagsToCompareOptions = InvertDictionary(CompareOptionsToLcmapFlags);
}
/// <summary>
/// Convert a double (OA date time format) to a DateTime. Unlike DateTime.FromOADate
/// this doesn't throw exceptions.
/// </summary>
/// <param name="d">The double value.</param>
/// <returns>A DateTime.</returns>
public static DateTime ConvertDoubleToDateTime(double d)
{
try
{
return LibraryHelpers.FromOADate(d);
}
catch (ArgumentException)
{
// Not all double values are valid OADates. We deal with out-of-range values
// by returning either min or max
return d < 0 ? DateTime.MinValue : DateTime.MaxValue;
}
}
/// <summary>
/// Given flags for LCMapFlags, turn them into compare options. Unknown options
/// are ignored.
/// </summary>
/// <param name="lcmapFlags">LCMapString flags.</param>
/// <returns>CompareOptions describing the (known) flags.</returns>
[CLSCompliant(false)]
public static CompareOptions CompareOptionsFromLCMapFlags(uint lcmapFlags)
{
// This should be a template, but there isn't an elegant way to express than with C# generics
CompareOptions options = CompareOptions.None;
foreach (uint flag in LcmapFlagsToCompareOptions.Keys)
{
if (flag == (lcmapFlags & flag))
{
options |= LcmapFlagsToCompareOptions[flag];
}
}
return options;
}
/// <summary>
/// Give CompareOptions, turn them into flags from LCMapString. Unknown options are ignored.
/// </summary>
/// <param name="compareOptions">The options to convert.</param>
/// <returns>The LCMapString flags that match the compare options. Unsupported options are ignored.</returns>
[CLSCompliant(false)]
public static uint LCMapFlagsFromCompareOptions(CompareOptions compareOptions)
{
// This should be a template, but there isn't an elegant way to express than with C# generics
uint flags = 0;
foreach (CompareOptions option in CompareOptionsToLcmapFlags.Keys)
{
if (option == (compareOptions & option))
{
flags |= CompareOptionsToLcmapFlags[option];
}
}
return flags;
}
/// <summary>
/// Given a Key=>Value dictionary create an inverted dictionary that maps Value=>Key.
/// </summary>
/// <typeparam name="TValue">The new value type (the key of the current dictionary).</typeparam>
/// <typeparam name="TKey">The new key type (the value if the current dictionary).</typeparam>
/// <param name="dict">The dictionary to invert.</param>
/// <returns>An inverted dictionary.</returns>
private static IDictionary<TKey, TValue> InvertDictionary<TValue, TKey>(ICollection<KeyValuePair<TValue, TKey>> dict)
{
var invertedDict = new Dictionary<TKey, TValue>(dict.Count);
foreach (KeyValuePair<TValue, TKey> entry in dict)
{
invertedDict.Add(entry.Value, entry.Key);
}
return invertedDict;
}
/// <summary>
/// This class contains the unmanaged constants used in the conversion.
/// </summary>
internal static class NativeMethods
{
#region Win32 Constants
/// <summary>
/// Ignore case.
/// </summary>
public const uint NORM_IGNORECASE = 0x00000001;
/// <summary>
/// Ignore nonspacing chars.
/// </summary>
public const uint NORM_IGNORENONSPACE = 0x00000002;
/// <summary>
/// Ignore symbols.
/// </summary>
public const uint NORM_IGNORESYMBOLS = 0x00000004;
/// <summary>
/// Ignore kanatype.
/// </summary>
public const uint NORM_IGNOREKANATYPE = 0x00010000;
/// <summary>
/// Ignore width.
/// </summary>
public const uint NORM_IGNOREWIDTH = 0x00020000;
/// <summary>
/// Treat punctuation the same as symbols.
/// </summary>
public const uint SORT_STRINGSORT = 0x00001000;
/// <summary>
/// Produce a normalized wide-character sort key.
/// </summary>
public const uint LCMAP_SORTKEY = 0x00000400;
#endregion Win32 Constants
}
}
}

View File

@ -1,70 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="DateTimeColumnValue.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
/// <summary>
/// A <see cref="Guid"/> column value.
/// </summary>
public class DateTimeColumnValue : ColumnValueOfStruct<DateTime>
{
/// <summary>
/// Gets the size of the value in the column. This returns 0 for
/// variable sized columns (i.e. binary and string).
/// </summary>
protected override int Size
{
[DebuggerStepThrough]
get { return sizeof(double); }
}
/// <summary>
/// Recursive SetColumns method for data pinning. This populates the buffer and
/// calls the inherited SetColumns method.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to set the columns in. An update should be prepared.
/// </param>
/// <param name="columnValues">
/// Column values to set.
/// </param>
/// <param name="nativeColumns">
/// Structures to put the pinned data in.
/// </param>
/// <param name="i">Offset of this object in the array.</param>
/// <returns>An error code.</returns>
internal override unsafe int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i)
{
var data = this.Value.GetValueOrDefault().ToOADate();
return this.SetColumns(sesid, tableid, columnValues, nativeColumns, i, &data, sizeof(double), this.Value.HasValue);
}
/// <summary>
/// Given data retrieved from ESENT, decode the data and set the value in the ColumnValue object.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within the bytes.</param>
/// <param name="count">The number of bytes to decode.</param>
/// <param name="err">The error returned from ESENT.</param>
protected override void GetValueFromBytes(byte[] value, int startIndex, int count, int err)
{
if (JET_wrn.ColumnNull == (JET_wrn)err)
{
this.Value = null;
}
else
{
this.CheckDataCount(count);
double d = BitConverter.ToDouble(value, startIndex);
this.Value = Conversions.ConvertDoubleToDateTime(d);
}
}
}
}

View File

@ -1,69 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="DoubleColumnValue.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
/// <summary>
/// A <see cref="double"/> column value.
/// </summary>
public class DoubleColumnValue : ColumnValueOfStruct<double>
{
/// <summary>
/// Gets the size of the value in the column. This returns 0 for
/// variable sized columns (i.e. binary and string).
/// </summary>
protected override int Size
{
[DebuggerStepThrough]
get { return sizeof(double); }
}
/// <summary>
/// Recursive SetColumns method for data pinning. This populates the buffer and
/// calls the inherited SetColumns method.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to set the columns in. An update should be prepared.
/// </param>
/// <param name="columnValues">
/// Column values to set.
/// </param>
/// <param name="nativeColumns">
/// Structures to put the pinned data in.
/// </param>
/// <param name="i">Offset of this object in the array.</param>
/// <returns>An error code.</returns>
internal override unsafe int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i)
{
var data = this.Value.GetValueOrDefault();
return this.SetColumns(sesid, tableid, columnValues, nativeColumns, i, &data, sizeof(double), this.Value.HasValue);
}
/// <summary>
/// Given data retrieved from ESENT, decode the data and set the value in the ColumnValue object.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within the bytes.</param>
/// <param name="count">The number of bytes to decode.</param>
/// <param name="err">The error returned from ESENT.</param>
protected override void GetValueFromBytes(byte[] value, int startIndex, int count, int err)
{
if (JET_wrn.ColumnNull == (JET_wrn)err)
{
this.Value = null;
}
else
{
this.CheckDataCount(count);
this.Value = BitConverter.ToDouble(value, startIndex);
}
}
}
}

View File

@ -1,172 +0,0 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="DurableCommitCallback.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
// <summary>
// Callback for JET_param JET_paramDurableCommitCallback.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop.Windows8
{
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Reflection;
#if !MANAGEDESENT_ON_CORECLR
using System.Runtime.CompilerServices;
#endif
using Microsoft.Isam.Esent.Interop.Implementation;
/// <summary>
/// A class which wraps the callback dealing with durable commits.
/// </summary>
public class DurableCommitCallback : EsentResource
{
/// <summary>
/// API call tracing.
/// </summary>
private static readonly TraceSwitch TraceSwitch = new TraceSwitch("ESENT DurableCommitCallback", "Wrapper around unmanaged ESENT durable commit callback");
/// <summary>
/// Instance associated with this callback.
/// </summary>
private JET_INSTANCE instance;
/// <summary>
/// Hold a reference to the delegate so that it doesn't get garbage-collected.
/// </summary>
private JET_PFNDURABLECOMMITCALLBACK wrappedCallback;
/// <summary>
/// Hold a reference to the delegate so that it doesn't get garbage-collected.
/// </summary>
[SuppressMessage("Exchange.Performance", "EX0023:DeadVariableDetector", Justification = "Need to hold on to a reference to the callback, so that it does not get garbage collected.")]
private NATIVE_JET_PFNDURABLECOMMITCALLBACK wrapperCallback;
/// <summary>
/// Initializes a new instance of the <see cref="DurableCommitCallback"/> class.
/// The constructor.
/// </summary>
/// <param name="instance">
/// The instance with which to associate the callback.
/// </param>
/// <param name="wrappedCallback">
/// The managed code callback to call.
/// </param>
public DurableCommitCallback(
JET_INSTANCE instance,
JET_PFNDURABLECOMMITCALLBACK wrappedCallback)
{
this.instance = instance;
this.wrappedCallback = wrappedCallback;
this.wrapperCallback = this.NativeDurableCommitCallback;
#if !MANAGEDESENT_ON_WSA // RuntimeHelpers works differently in Windows Store Apps.
if (this.wrappedCallback != null)
{
RuntimeHelpers.PrepareMethod(this.wrappedCallback.Method.MethodHandle);
}
RuntimeHelpers.PrepareMethod(typeof(DurableCommitCallback).GetMethod("NativeDurableCommitCallback", BindingFlags.NonPublic | BindingFlags.Instance).MethodHandle);
#endif
InstanceParameters instanceParameters = new InstanceParameters(this.instance);
// This might be null.
instanceParameters.SetDurableCommitCallback(this.wrapperCallback);
this.ResourceWasAllocated();
}
/// <summary>
/// Generate a string representation of the structure.
/// </summary>
/// <returns>The structure as a string.</returns>
public override string ToString()
{
return string.Format(
CultureInfo.InvariantCulture,
"DurableCommitCallback({0})",
this.instance.ToString());
}
/// <summary>
/// Terminate the durable commit session.
/// </summary>
public void End()
{
this.CheckObjectIsNotDisposed();
this.ReleaseResource();
}
/// <summary>
/// Free the durable commit session.
/// We do not try to set the instance parameter to null, since the callback is disposed after JetTerm and
/// the callback cannot be set after JetTerm.
/// </summary>
protected override void ReleaseResource()
{
this.instance = JET_INSTANCE.Nil;
this.wrappedCallback = null;
this.wrapperCallback = null;
this.ResourceWasReleased();
}
/// <summary>
/// The proxy callback function to call the user-defined managed delegate.
/// </summary>
/// <param name="instance">
/// The instance.
/// </param>
/// <param name="commitIdSeen">
/// The commit-id flushed.
/// </param>
/// <param name="grbit">
/// Reserved currently.
/// </param>
/// <returns>
/// An error code.
/// </returns>
private JET_err NativeDurableCommitCallback(
IntPtr instance,
ref NATIVE_COMMIT_ID commitIdSeen,
uint grbit)
{
RuntimeHelpers.PrepareConstrainedRegions();
try
{
JET_INSTANCE jetInstance = new JET_INSTANCE()
{
Value = instance
};
if (this.instance != jetInstance)
{
// We assume it's only called on one instance at a time. The only thing
// we really care about is serialization of the byte array.
//
// It would be nice to throw an error, but we're going back to real
// code, which doesn't deal with managed exceptions well.
return JET_err.CallbackFailed;
}
JET_COMMIT_ID commitId = new JET_COMMIT_ID(commitIdSeen);
return this.wrappedCallback(jetInstance, commitId, (DurableCommitCallbackGrbit)grbit);
}
catch (Exception ex)
{
Trace.WriteLineIf(
TraceSwitch.TraceWarning, string.Format(CultureInfo.InvariantCulture, "Caught Exception {0}", ex));
JetApi.ReportUnhandledException(ex, "Unhandled exception during NativeDurableCommitCallback");
// This should never be executed, but the compiler doesn't know it.
return JET_err.CallbackFailed;
}
}
}
}

View File

@ -1,121 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="EnumeratedColumn.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Globalization;
/// <summary>
/// The values for a given column as generated by Api.EnumerateColumns.
/// </summary>
public class EnumeratedColumn
{
/// <summary>
/// Gets or sets the column ID of this set of column values.
/// </summary>
public JET_COLUMNID Id { get; set; }
/// <summary>
/// Gets or sets the status of this column id.
/// </summary>
/// <seealso cref="JET_err.Success"/>
/// <seealso cref="JET_err.BadColumnId"/>
/// <seealso cref="JET_err.ColumnNotFound"/>
public JET_err Error { get; set; }
/// <summary>
/// Gets or sets the status of this set of column values.
/// </summary>
/// <seealso cref="JET_wrn.Success"/>
/// <seealso cref="JET_wrn.ColumnDefault"/>
/// <seealso cref="JET_wrn.ColumnNull"/>
/// <seealso cref="JET_wrn.ColumnPresent"/>
/// <seealso cref="JET_wrn.ColumnSkipped"/>
public JET_wrn Warning { get; set; }
/// <summary>
/// Gets or sets the column values enumerated.
/// </summary>
/// <remarks>
/// This will be null if the column is null or the column values were not provided.
/// </remarks>
public Value[] Values { get; set; }
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="EnumeratedColumn"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="EnumeratedColumn"/>.
/// </returns>
public override string ToString()
{
return string.Format(
CultureInfo.InvariantCulture,
"EnumeratedColumn(0x{0:x}: {1} Values[{2}])",
this.Id,
this.Error != JET_err.Success ? this.Error.ToString() : this.Warning.ToString(),
this.Values.Length);
}
/// <summary>
/// A single column value.
/// </summary>
public class Value
{
/// <summary>
/// Gets or sets the ordinal of this column value.
/// </summary>
/// <remarks>
/// The lowest valid ordinal is one.
/// This is the same as the "itagSequence" of the column value.
/// </remarks>
public int Ordinal { get; set; }
/// <summary>
/// Gets or sets the status of this column value.
/// </summary>
/// <seealso cref="JET_wrn.Success"/>
/// <seealso cref="JET_wrn.ColumnDefault"/>
/// <seealso cref="JET_wrn.ColumnNotInRecord"/>
/// <seealso cref="JET_wrn.ColumnNull"/>
/// <seealso cref="JET_wrn.ColumnPresent"/>
/// <seealso cref="JET_wrn.ColumnSkipped"/>
/// <seealso cref="JET_wrn.ColumnTruncated"/>
public JET_wrn Warning { get; set; }
/// <summary>
/// Gets or sets the column value as bytes.
/// </summary>
/// <remarks>
/// This will be null if the column is null or the column values were not provided.
/// This will be truncated if Warning is <see cref="JET_wrn.ColumnTruncated"/>.
/// </remarks>
public byte[] Bytes { get; set; }
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="EnumeratedColumn.Value"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="EnumeratedColumn.Value"/>.
/// </returns>
public override string ToString()
{
const int MaxLength = 16;
return string.Format(
CultureInfo.InvariantCulture,
"EnumeratedColumn.Value({0}: {1} Bytes[{2}] = {3}{4}{5}{6})",
this.Ordinal,
this.Warning,
this.Bytes.Length,
'{',
BitConverter.ToString(this.Bytes, 0, Math.Min(this.Bytes.Length, MaxLength)),
this.Bytes.Length > MaxLength ? "..." : string.Empty,
'}');
}
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,351 +0,0 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.10.35122.118
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{18B3E50E-454E-49DB-A92F-E1D7DAD2AF7D}"
ProjectSection(SolutionItems) = preProject
CodeCoverage.testrunconfig = CodeCoverage.testrunconfig
esent.vsmdi = esent.vsmdi
Normal.testrunconfig = Normal.testrunconfig
EndProjectSection
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EsentInterop", "EsentInterop.csproj", "{E929E163-52A0-4AAC-917B-6D7FAF70C45E}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DbUtil", "..\EsentInteropSamples\DbUtil\DbUtil.csproj", "{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "isam", "..\isam\isam.csproj", "{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StockSample", "..\EsentInteropSamples\StockSample\StockSample.csproj", "{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EsentCollections", "..\EsentCollections\EsentCollections.csproj", "{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HelloWorld", "..\EsentCollectionsSamples\HelloWorld\HelloWorld.csproj", "{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RssDictionarySample", "..\EsentCollectionsSamples\RssDictionarySample\RssDictionarySample.csproj", "{134FBC80-2E23-451B-A6B3-72B0AA2234F9}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EsentInteropTests", "..\EsentInteropTests\EsentInteropTests.csproj", "{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EsentCollectionsTests", "..\EsentCollectionsTests\EsentCollectionsTests.csproj", "{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "IsamUnitTests", "..\isamunittests\IsamUnitTests.csproj", "{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DbUtilTests", "..\EsentInteropSamples\DbUtilTests\DbUtilTests.csproj", "{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "EsentSample", "..\EsentInteropSamples\EsentSample\EsentSample.csproj", "{44D46916-891F-435F-B914-AE8AC80613FD}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BasicTest", "..\EsentInteropSamples\BasicTest\BasicTest.csproj", "{08819B49-02B8-4F93-A143-F9B0461CEA64}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UWPSample", "..\UWPSample\UWPSample.csproj", "{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|ARM = Debug|ARM
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|ARM = Release|ARM
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Debug|ARM.ActiveCfg = Debug|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Debug|ARM.Build.0 = Debug|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Debug|ARM64.Build.0 = Debug|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Debug|x64.ActiveCfg = Debug|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Debug|x64.Build.0 = Debug|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Debug|x86.ActiveCfg = Debug|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Debug|x86.Build.0 = Debug|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Release|Any CPU.Build.0 = Release|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Release|ARM.ActiveCfg = Release|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Release|ARM.Build.0 = Release|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Release|ARM64.ActiveCfg = Release|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Release|ARM64.Build.0 = Release|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Release|x64.ActiveCfg = Release|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Release|x64.Build.0 = Release|Any CPU
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Release|x86.ActiveCfg = Release|x86
{E929E163-52A0-4AAC-917B-6D7FAF70C45E}.Release|x86.Build.0 = Release|x86
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Debug|ARM.ActiveCfg = Debug|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Debug|ARM.Build.0 = Debug|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Debug|ARM64.Build.0 = Debug|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Debug|x64.ActiveCfg = Debug|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Debug|x64.Build.0 = Debug|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Debug|x86.ActiveCfg = Debug|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Debug|x86.Build.0 = Debug|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Release|Any CPU.Build.0 = Release|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Release|ARM.ActiveCfg = Release|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Release|ARM.Build.0 = Release|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Release|ARM64.ActiveCfg = Release|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Release|ARM64.Build.0 = Release|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Release|x64.ActiveCfg = Release|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Release|x64.Build.0 = Release|Any CPU
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Release|x86.ActiveCfg = Release|x86
{E0B163B0-5AC6-4304-B932-BFC1F6A2A4EB}.Release|x86.Build.0 = Release|x86
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Debug|ARM.ActiveCfg = Debug|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Debug|ARM.Build.0 = Debug|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Debug|ARM64.Build.0 = Debug|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Debug|x64.ActiveCfg = Debug|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Debug|x64.Build.0 = Debug|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Debug|x86.ActiveCfg = Debug|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Debug|x86.Build.0 = Debug|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Release|Any CPU.Build.0 = Release|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Release|ARM.ActiveCfg = Release|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Release|ARM.Build.0 = Release|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Release|ARM64.ActiveCfg = Release|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Release|ARM64.Build.0 = Release|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Release|x64.ActiveCfg = Release|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Release|x64.Build.0 = Release|Any CPU
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Release|x86.ActiveCfg = Release|x86
{21CC632C-B09A-4DB7-BD6E-7F7D2716F58F}.Release|x86.Build.0 = Release|x86
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Debug|ARM.ActiveCfg = Debug|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Debug|ARM.Build.0 = Debug|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Debug|ARM64.Build.0 = Debug|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Debug|x64.ActiveCfg = Debug|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Debug|x64.Build.0 = Debug|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Debug|x86.ActiveCfg = Debug|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Debug|x86.Build.0 = Debug|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Release|Any CPU.Build.0 = Release|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Release|ARM.ActiveCfg = Release|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Release|ARM.Build.0 = Release|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Release|ARM64.ActiveCfg = Release|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Release|ARM64.Build.0 = Release|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Release|x64.ActiveCfg = Release|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Release|x64.Build.0 = Release|Any CPU
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Release|x86.ActiveCfg = Release|x86
{B0E6D3AB-26F8-4A77-A7E1-D8024B8FFFCF}.Release|x86.Build.0 = Release|x86
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Debug|ARM.ActiveCfg = Debug|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Debug|ARM.Build.0 = Debug|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Debug|ARM64.Build.0 = Debug|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Debug|x64.ActiveCfg = Debug|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Debug|x64.Build.0 = Debug|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Debug|x86.ActiveCfg = Debug|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Debug|x86.Build.0 = Debug|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Release|Any CPU.Build.0 = Release|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Release|ARM.ActiveCfg = Release|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Release|ARM.Build.0 = Release|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Release|ARM64.ActiveCfg = Release|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Release|ARM64.Build.0 = Release|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Release|x64.ActiveCfg = Release|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Release|x64.Build.0 = Release|Any CPU
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Release|x86.ActiveCfg = Release|x86
{CF2D4EE4-0D11-404D-B800-C4DCFEC42588}.Release|x86.Build.0 = Release|x86
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Debug|ARM.ActiveCfg = Debug|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Debug|ARM.Build.0 = Debug|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Debug|ARM64.Build.0 = Debug|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Debug|x64.ActiveCfg = Debug|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Debug|x64.Build.0 = Debug|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Debug|x86.ActiveCfg = Debug|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Debug|x86.Build.0 = Debug|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Release|Any CPU.Build.0 = Release|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Release|ARM.ActiveCfg = Release|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Release|ARM.Build.0 = Release|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Release|ARM64.ActiveCfg = Release|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Release|ARM64.Build.0 = Release|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Release|x64.ActiveCfg = Release|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Release|x64.Build.0 = Release|Any CPU
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Release|x86.ActiveCfg = Release|x86
{8341DE8C-5BC7-461F-B42D-AA2B72586A5C}.Release|x86.Build.0 = Release|x86
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Debug|ARM.ActiveCfg = Debug|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Debug|ARM.Build.0 = Debug|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Debug|ARM64.Build.0 = Debug|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Debug|x64.ActiveCfg = Debug|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Debug|x64.Build.0 = Debug|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Debug|x86.ActiveCfg = Debug|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Debug|x86.Build.0 = Debug|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Release|Any CPU.Build.0 = Release|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Release|ARM.ActiveCfg = Release|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Release|ARM.Build.0 = Release|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Release|ARM64.ActiveCfg = Release|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Release|ARM64.Build.0 = Release|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Release|x64.ActiveCfg = Release|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Release|x64.Build.0 = Release|Any CPU
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Release|x86.ActiveCfg = Release|x86
{134FBC80-2E23-451B-A6B3-72B0AA2234F9}.Release|x86.Build.0 = Release|x86
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Debug|ARM.ActiveCfg = Debug|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Debug|ARM.Build.0 = Debug|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Debug|ARM64.Build.0 = Debug|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Debug|x64.ActiveCfg = Debug|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Debug|x64.Build.0 = Debug|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Debug|x86.ActiveCfg = Debug|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Debug|x86.Build.0 = Debug|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Release|Any CPU.Build.0 = Release|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Release|ARM.ActiveCfg = Release|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Release|ARM.Build.0 = Release|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Release|ARM64.ActiveCfg = Release|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Release|ARM64.Build.0 = Release|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Release|x64.ActiveCfg = Release|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Release|x64.Build.0 = Release|Any CPU
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Release|x86.ActiveCfg = Release|x86
{85B2B7BB-BF95-42DF-8CBF-348AEF63BD1F}.Release|x86.Build.0 = Release|x86
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Debug|ARM.ActiveCfg = Debug|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Debug|ARM.Build.0 = Debug|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Debug|ARM64.Build.0 = Debug|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Debug|x64.ActiveCfg = Debug|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Debug|x64.Build.0 = Debug|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Debug|x86.ActiveCfg = Debug|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Debug|x86.Build.0 = Debug|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Release|Any CPU.Build.0 = Release|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Release|ARM.ActiveCfg = Release|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Release|ARM.Build.0 = Release|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Release|ARM64.ActiveCfg = Release|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Release|ARM64.Build.0 = Release|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Release|x64.ActiveCfg = Release|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Release|x64.Build.0 = Release|Any CPU
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Release|x86.ActiveCfg = Release|x86
{D3A1C1C8-6119-4827-AC24-1FF49FACFD4D}.Release|x86.Build.0 = Release|x86
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Debug|ARM.ActiveCfg = Debug|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Debug|ARM.Build.0 = Debug|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Debug|ARM64.Build.0 = Debug|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Debug|x64.ActiveCfg = Debug|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Debug|x64.Build.0 = Debug|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Debug|x86.ActiveCfg = Debug|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Debug|x86.Build.0 = Debug|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Release|Any CPU.ActiveCfg = Debug|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Release|Any CPU.Build.0 = Debug|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Release|ARM.ActiveCfg = Release|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Release|ARM.Build.0 = Release|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Release|ARM64.ActiveCfg = Release|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Release|ARM64.Build.0 = Release|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Release|x64.ActiveCfg = Release|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Release|x64.Build.0 = Release|Any CPU
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Release|x86.ActiveCfg = Release|x86
{6AC9C0BE-6BCE-493F-BD80-6F2247CB669D}.Release|x86.Build.0 = Release|x86
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Debug|ARM.ActiveCfg = Debug|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Debug|ARM.Build.0 = Debug|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Debug|ARM64.Build.0 = Debug|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Debug|x64.ActiveCfg = Debug|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Debug|x64.Build.0 = Debug|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Debug|x86.ActiveCfg = Debug|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Debug|x86.Build.0 = Debug|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Release|Any CPU.Build.0 = Release|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Release|ARM.ActiveCfg = Release|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Release|ARM.Build.0 = Release|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Release|ARM64.ActiveCfg = Release|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Release|ARM64.Build.0 = Release|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Release|x64.ActiveCfg = Release|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Release|x64.Build.0 = Release|Any CPU
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Release|x86.ActiveCfg = Release|x86
{C9B82A4F-8306-41A9-91DA-1BA5080F1DB0}.Release|x86.Build.0 = Release|x86
{44D46916-891F-435F-B914-AE8AC80613FD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Debug|Any CPU.Build.0 = Debug|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Debug|ARM.ActiveCfg = Debug|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Debug|ARM.Build.0 = Debug|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Debug|ARM64.Build.0 = Debug|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Debug|x64.ActiveCfg = Debug|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Debug|x64.Build.0 = Debug|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Debug|x86.ActiveCfg = Debug|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Debug|x86.Build.0 = Debug|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Release|Any CPU.ActiveCfg = Release|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Release|Any CPU.Build.0 = Release|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Release|ARM.ActiveCfg = Release|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Release|ARM.Build.0 = Release|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Release|ARM64.ActiveCfg = Release|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Release|ARM64.Build.0 = Release|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Release|x64.ActiveCfg = Release|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Release|x64.Build.0 = Release|Any CPU
{44D46916-891F-435F-B914-AE8AC80613FD}.Release|x86.ActiveCfg = Release|x86
{44D46916-891F-435F-B914-AE8AC80613FD}.Release|x86.Build.0 = Release|x86
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Debug|Any CPU.Build.0 = Debug|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Debug|ARM.ActiveCfg = Debug|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Debug|ARM.Build.0 = Debug|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Debug|ARM64.Build.0 = Debug|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Debug|x64.ActiveCfg = Debug|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Debug|x64.Build.0 = Debug|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Debug|x86.ActiveCfg = Debug|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Debug|x86.Build.0 = Debug|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Release|Any CPU.ActiveCfg = Release|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Release|Any CPU.Build.0 = Release|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Release|ARM.ActiveCfg = Release|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Release|ARM.Build.0 = Release|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Release|ARM64.ActiveCfg = Release|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Release|ARM64.Build.0 = Release|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Release|x64.ActiveCfg = Release|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Release|x64.Build.0 = Release|Any CPU
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Release|x86.ActiveCfg = Release|x86
{08819B49-02B8-4F93-A143-F9B0461CEA64}.Release|x86.Build.0 = Release|x86
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|Any CPU.ActiveCfg = Debug|x86
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|ARM.ActiveCfg = Debug|ARM
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|ARM.Build.0 = Debug|ARM
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|ARM.Deploy.0 = Debug|ARM
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|ARM64.ActiveCfg = Debug|ARM64
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|ARM64.Build.0 = Debug|ARM64
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|ARM64.Deploy.0 = Debug|ARM64
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|x64.ActiveCfg = Debug|x64
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|x64.Build.0 = Debug|x64
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|x64.Deploy.0 = Debug|x64
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|x86.ActiveCfg = Debug|x86
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|x86.Build.0 = Debug|x86
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Debug|x86.Deploy.0 = Debug|x86
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|Any CPU.ActiveCfg = Release|x86
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|ARM.ActiveCfg = Release|ARM
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|ARM.Build.0 = Release|ARM
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|ARM.Deploy.0 = Release|ARM
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|ARM64.ActiveCfg = Release|ARM64
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|ARM64.Build.0 = Release|ARM64
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|ARM64.Deploy.0 = Release|ARM64
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|x64.ActiveCfg = Release|x64
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|x64.Build.0 = Release|x64
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|x64.Deploy.0 = Release|x64
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|x86.ActiveCfg = Release|x86
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|x86.Build.0 = Release|x86
{B1427E8D-9175-42BE-8B90-A5A9CB4AAD51}.Release|x86.Deploy.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6A6764EF-3A8F-46BF-8CC8-C07DE889160A}
EndGlobalSection
GlobalSection(TestCaseManagementSettings) = postSolution
CategoryFile = Esent.vsmdi
EndGlobalSection
EndGlobal

View File

@ -1,6 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<TestLists xmlns="http://microsoft.com/schemas/VisualStudio/TeamTest/2010">
<TestList name="Lists of Tests" id="8c43106b-9dc1-4907-a29f-aa66a61bf5b6">
<RunConfiguration id="6c3d561f-b13d-4563-9e69-90f00c61747b" name="Normal" storage="normal.testrunconfig" type="Microsoft.VisualStudio.TestTools.Common.TestRunConfiguration, Microsoft.VisualStudio.QualityTools.Common, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
</TestList>
</TestLists>

View File

@ -1 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><ItemProperties xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><Properties><Property><Name>svn:mime-type</Name><Value>application/octet-stream</Value></Property></Properties></ItemProperties>

View File

@ -1,82 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="AssemblyInfo.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("EsentInterop")]
[assembly: AssemblyDescription("Managed interop code for esent.dll")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("EsentInterop")]
[assembly: AssemblyCopyright("Copyright (c) Microsoft")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
[assembly: CLSCompliant(true)]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
//
// Version history:
// 1.6.0.0
// 1.7.0.0
// 1.8.0.0 Support new Windows user interface (As of Win8 Beta build).
// 1.8.1.0 2012.11.18. Some minor updates, including some perf updates.
// 1.8.2.0 2012.11.19. Signed.
// 1.8.3.0 2013.03.25. Signed and Strong Named. Renamed 'Metro' to 'Wsa' (Windows Store App)
// 1.8.4.0 2013.12.23. Updated for Windows 8.1.
// 1.9.0.0 2013.12.23. Go back to targetting framework 4.0.
// 1.9.1.0 2014.07.18. PersistentDictionary gets binary blobs; added Isam layer.
// 1.9.2.0 2014.09.11. Isam is placed in the Microsoft.Database namespace.
// 1.9.3.0 2015.08.11. Dependence added from Collections to Isam dll for configsets.
// 1.9.3.2 2015.09.02. Some bug fixes; go back to Framework 4.0
// 1.9.3.3 2016.03.01. Some bug and perf fixes.
// 1.9.4 2016.06.28. Some bug fixes.
// 1.9.4.1 2017.08.30. Adding JetGetIndexInfo that returns JET_INDEXCREATE.
[assembly: AssemblyVersion("1.9.4.1")]
[assembly: AssemblyFileVersion("1.9.4.1")]
#if STRONG_NAMED
[assembly: InternalsVisibleTo("EsentInteropWsaTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")]
[assembly: InternalsVisibleTo("Esent.Isam, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")]
[assembly: InternalsVisibleTo("InteropApiTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")]
[assembly: InternalsVisibleTo("IsamUnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")]
[assembly: InternalsVisibleTo("Pixie, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")]
[assembly: InternalsVisibleTo("PixieTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100B5FC90E7027F67871E773A8FDE8938C81DD402BA65B9201D60593E96C492651E889CC13F1415EBB53FAC1131AE0BD333C5EE6021672D9718EA31A8AEBD0DA0072F25D87DBA6FC90FFD598ED4DA35E44C398C454307E8E33B8426143DAEC9F596836F97C8F74750E5975C64E2189F45DEF46B2A2B1247ADC3652BF5C308055DA9")]
// This assembly is generated by Rhino.Mocks
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2,PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
#else
[assembly: InternalsVisibleTo("InteropApiTests")]
[assembly: InternalsVisibleTo("IsamUnitTests")]
[assembly: InternalsVisibleTo("EsentInteropTestsImmersive")]
[assembly: InternalsVisibleTo("EsentInteropWsaTests")]
[assembly: InternalsVisibleTo("Esent.Isam")]
[assembly: InternalsVisibleTo("Pixie")]
[assembly: InternalsVisibleTo("PixieTests")]
// This assembly is generated by Rhino.Mocks
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]
#endif

View File

@ -1,37 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="CallbackDataConverter.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Runtime.InteropServices;
/// <summary>
/// Methods to convert data objects used in callbacks.
/// </summary>
internal static class CallbackDataConverter
{
/// <summary>
/// Get the managed data object from the unmanaged data.
/// </summary>
/// <param name="nativeData">The native data.</param>
/// <param name="snp">The SNP (used to determine the type of object).</param>
/// <param name="snt">The SNT (used to determine the type of object).</param>
/// <returns>The managed data object.</returns>
public static object GetManagedData(IntPtr nativeData, JET_SNP snp, JET_SNT snt)
{
if (IntPtr.Zero != nativeData && JET_SNT.Progress == snt)
{
NATIVE_SNPROG native = (NATIVE_SNPROG)Marshal.PtrToStructure(nativeData, typeof(NATIVE_SNPROG));
JET_SNPROG managed = new JET_SNPROG();
managed.SetFromNative(native);
return managed;
}
return null;
}
}
}

View File

@ -1,263 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="EsentImplementationStubs.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
// <summary>
// Class stubs to allow compiling on CoreClr.
// </summary>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop.Implementation
{
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Text;
/// <summary>
/// A fake class to allow compilation on platforms that lack this functionality.
/// </summary>
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass",
Justification = "Reviewed. Suppression is OK here because it's a collection of trivial classes.")]
public class Trace
{
/// <summary>
/// A fake function to allow compilation on platforms that lack this functionality.
/// </summary>
/// <param name="condition">
/// The condition.
/// </param>
/// <param name="message">
/// The message.
/// </param>
[ConditionalAttribute("TRACE")]
public static void WriteLineIf(bool condition, string message)
{
}
/// <summary>
/// A fake function to allow compilation on platforms that lack this functionality.
/// </summary>
/// <param name="condition">
/// The condition.
/// </param>
/// <param name="message">
/// The message.
/// </param>
[ConditionalAttribute("TRACE")]
public static void WriteLineIf(bool condition, object message)
{
}
/// <summary>
/// Prints out the object's contents.
/// </summary>
/// <returns>A string represenetation or the object.</returns>
public override string ToString()
{
return base.ToString();
}
}
/// <summary>
/// A fake class to allow compilation on platforms that lack this class.
/// </summary>
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass",
Justification = "Reviewed. Suppression is OK here because it's a collection of trivial classes.")]
internal static class RuntimeHelpers
{
/// <summary>
/// A fake function to allow compilation on platforms that lack this functionality.
/// </summary>
public static void PrepareConstrainedRegions()
{
}
/// <summary>
/// A fake function to allow compilation on platforms that lack this functionality.
/// </summary>
/// <param name="method">
/// The method.
/// </param>
public static void PrepareMethod(RuntimeMethodHandle method)
{
}
}
/// <summary>
/// Ascii encoding is not available on Core Clr. But UTF-8 is.
/// This class will reject any character that results in an
/// extended value.
/// </summary>
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass",
Justification = "Reviewed. Suppression is OK here because it's a collection of trivial classes.")]
internal class SlowAsciiEncoding : UTF8Encoding
{
/// <summary>
/// The standard encoding object.
/// </summary>
private static SlowAsciiEncoding slowAsciiEncoding = new SlowAsciiEncoding();
/// <summary>
/// Gets an Encoding object.
/// </summary>
public static Encoding Encoding
{
get
{
return slowAsciiEncoding;
}
}
#if !MANAGEDESENT_ON_WSA
/// <summary>
/// Converts a string to the byte representation.
/// </summary>
/// <param name="chars">
/// The chars.
/// </param>
/// <param name="charCount">
/// The char count.
/// </param>
/// <param name="bytes">
/// The bytes.
/// </param>
/// <param name="byteCount">
/// The byte count.
/// </param>
/// <returns>
/// A count of bytes stored.
/// </returns>
public override unsafe int GetBytes(char* chars, int charCount, byte* bytes, int byteCount)
{
IntPtr toFree;
char* charsToTranslate = this.SanitizeString(chars, charCount, out toFree);
int toReturn = base.GetBytes(charsToTranslate, charCount, bytes, byteCount);
LibraryHelpers.MarshalFreeHGlobal(toFree);
return toReturn;
}
#endif
/// <summary>
/// Converts a string to the byte representation.
/// </summary>
/// <param name="inputString">
/// The input string.
/// </param>
/// <returns>
/// The byte representation of the string.
/// </returns>
public override byte[] GetBytes(string inputString)
{
string stringToTranslate = this.SanitizeString(inputString);
return base.GetBytes(stringToTranslate);
}
/// <summary>
/// Converts a string to the byte representation.
/// </summary>
/// <param name="inputString">
/// The input string.
/// </param>
/// <param name="charIndex">
/// The char index.
/// </param>
/// <param name="charCount">
/// The char count.
/// </param>
/// <param name="bytes">
/// The bytes.
/// </param>
/// <param name="byteIndex">
/// The byte index.
/// </param>
/// <returns>
/// The byte representation of the string.
/// </returns>
public override int GetBytes(string inputString, int charIndex, int charCount, byte[] bytes, int byteIndex)
{
string stringToTranslate = this.SanitizeString(inputString);
return base.GetBytes(stringToTranslate, charIndex, charCount, bytes, byteIndex);
}
/// <summary>
/// Scans the string looking for unmappable characters in the ASCII set, and replaces
/// them with '?'.
/// </summary>
/// <param name="inputString">A unicode string with unknown characters.</param>
/// <returns>A string that has all legal ASCII characters.</returns>
private string SanitizeString(string inputString)
{
bool needToDuplicate = false;
string returnString = inputString;
foreach (char ch in inputString)
{
if (ch > 127)
{
needToDuplicate = true;
break;
}
}
if (needToDuplicate)
{
StringBuilder sb = new StringBuilder(inputString.Length);
foreach (char ch in inputString)
{
sb.Append(ch > 127 ? '?' : ch);
}
returnString = sb.ToString();
}
return returnString;
}
#if !MANAGEDESENT_ON_WSA
/// <summary>
/// Scans the string looking for unmappable characters in the ASCII set, and replaces
/// them with '?'.
/// </summary>
/// <param name="inputString">A unicode string with unknown characters.</param>
/// <param name="charCount">The length of the string to sanitize.</param>
/// <param name="allocedMemory">On output, a value that needs to be freed. Only used
/// if there are any untranslaable characters.</param>
/// <returns>A string that has all legal ASCII characters.</returns>
private unsafe char* SanitizeString(char* inputString, int charCount, out IntPtr allocedMemory)
{
allocedMemory = IntPtr.Zero;
bool needToDuplicate = false;
char* returnString = inputString;
for (int i = 0; i < charCount; ++i)
{
if (inputString[i] > 127)
{
needToDuplicate = true;
break;
}
}
if (needToDuplicate)
{
allocedMemory = LibraryHelpers.MarshalAllocHGlobal(charCount);
returnString = (char*)allocedMemory;
char* dest = returnString;
for (int i = 0; i < charCount; ++i)
{
dest[i] = inputString[i] > 127 ? '?' : inputString[i];
}
}
return returnString;
}
#endif
}
}

View File

@ -1,157 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="EsentJetApi.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
// <summary>
// JetApi code that is specific to ESENT.
// </summary>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop.Implementation
{
using System;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Threading;
/// <summary>
/// JetApi code that is specific to ESENT.
/// </summary>
internal sealed partial class JetApi
{
/// <summary>
/// Reports the exception to a central authority.
/// </summary>
/// <param name="exception">An unhandled exception.</param>
/// <param name="description">A string description of the scenario.</param>
internal static void ReportUnhandledException(
Exception exception,
string description)
{
}
/// <summary>
/// Calculates the capabilities of the current Esent version.
/// </summary>
private void DetermineCapabilities()
{
const int Server2003BuildNumber = 2700;
const int VistaBuildNumber = 6000;
const int Windows7BuildNumber = 7000; // includes beta as well as RTM (RTM is 7600)
const int Windows8BuildNumber = 8000; // includes beta as well as RTM (RTM is 9200)
const int Windows81BuildNumber = 9300; // includes beta as well as RTM (RTM is 9600)
const int Windows10BuildNumber = 9900; // includes beta as well as RTM (RTM is 10240)
// Create new capabilities, set as all false. This will allow
// us to call into Esent.
this.Capabilities = new JetCapabilities { ColumnsKeyMost = 12 };
var version = this.versionOverride;
if (version == 0)
{
version = this.GetVersionFromEsent();
}
var buildNumber = (int)((version & 0xFFFFFF) >> 8);
Trace.WriteLineIf(
TraceSwitch.TraceVerbose,
string.Format(CultureInfo.InvariantCulture, "Version = {0}, BuildNumber = {1}", version, buildNumber));
if (buildNumber >= Server2003BuildNumber)
{
Trace.WriteLineIf(TraceSwitch.TraceVerbose, "Supports Server 2003 features");
this.Capabilities.SupportsServer2003Features = true;
}
if (buildNumber >= VistaBuildNumber)
{
Trace.WriteLineIf(TraceSwitch.TraceVerbose, "Supports Vista features");
this.Capabilities.SupportsVistaFeatures = true;
Trace.WriteLineIf(TraceSwitch.TraceVerbose, "Supports Unicode paths");
this.Capabilities.SupportsUnicodePaths = true;
Trace.WriteLineIf(TraceSwitch.TraceVerbose, "Supports large keys");
this.Capabilities.SupportsLargeKeys = true;
Trace.WriteLineIf(TraceSwitch.TraceVerbose, "Supports 16-column keys");
this.Capabilities.ColumnsKeyMost = 16;
}
if (buildNumber >= Windows7BuildNumber)
{
Trace.WriteLineIf(TraceSwitch.TraceVerbose, "Supports Windows 7 features");
this.Capabilities.SupportsWindows7Features = true;
}
if (buildNumber >= Windows8BuildNumber)
{
Trace.WriteLineIf(TraceSwitch.TraceVerbose, "Supports Windows 8 features");
this.Capabilities.SupportsWindows8Features = true;
}
if (buildNumber >= Windows81BuildNumber)
{
Trace.WriteLineIf(TraceSwitch.TraceVerbose, "Supports Windows 8.1 features");
this.Capabilities.SupportsWindows81Features = true;
}
if (buildNumber >= Windows10BuildNumber)
{
Trace.WriteLineIf(TraceSwitch.TraceVerbose, "Supports Windows 10 features");
this.Capabilities.SupportsWindows10Features = true;
}
}
/// <summary>
/// Create an instance and get the current version of Esent.
/// </summary>
/// <returns>The current version of Esent.</returns>
private uint GetVersionFromEsent()
{
#if MANAGEDESENT_ON_WSA
// JetGetVersion isn't available in new Windows user interface, so we'll pretend it's always Win8:
return 8250 << 8;
#else
// Create a unique name so that multiple threads can call this simultaneously.
// This can happen if there are multiple AppDomains.
string instanceName = string.Format(CultureInfo.InvariantCulture, "GettingEsentVersion{0}", LibraryHelpers.GetCurrentManagedThreadId());
JET_INSTANCE instance = JET_INSTANCE.Nil;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
this.JetCreateInstance(out instance, instanceName);
this.JetSetSystemParameter(instance, JET_SESID.Nil, JET_param.Recovery, new IntPtr(0), "off");
this.JetSetSystemParameter(instance, JET_SESID.Nil, JET_param.NoInformationEvent, new IntPtr(1), null);
this.JetSetSystemParameter(instance, JET_SESID.Nil, JET_param.MaxTemporaryTables, new IntPtr(0), null);
this.JetSetSystemParameter(instance, JET_SESID.Nil, JET_param.MaxCursors, new IntPtr(16), null);
this.JetSetSystemParameter(instance, JET_SESID.Nil, JET_param.MaxOpenTables, new IntPtr(16), null);
this.JetSetSystemParameter(instance, JET_SESID.Nil, JET_param.MaxVerPages, new IntPtr(4), null);
this.JetSetSystemParameter(instance, JET_SESID.Nil, JET_param.MaxSessions, new IntPtr(1), null);
this.JetInit(ref instance);
JET_SESID sesid;
this.JetBeginSession(instance, out sesid, string.Empty, string.Empty);
try
{
uint version;
this.JetGetVersion(sesid, out version);
return version;
}
finally
{
this.JetEndSession(sesid, EndSessionGrbit.None);
}
}
finally
{
if (JET_INSTANCE.Nil != instance)
{
this.JetTerm(instance);
}
}
#endif
}
}
}

View File

@ -1,22 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="EsentNativeMethods.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
// <summary>
// NativeMethods code that is specific to ESENT.
// </summary>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop.Implementation
{
/// <summary>
/// Configuration for functions in esent.dll.
/// </summary>
internal static partial class NativeMethods
{
/// <summary>
/// The name of the DLL that the methods should be loaded from.
/// </summary>
private const string EsentDll = "esent.dll";
}
}

View File

@ -1,325 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="EsentStubAttributes.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
// <summary>
// Attribute stubs to allow compiling on CoreClr.
// </summary>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics.CodeAnalysis;
#if !MANAGEDESENT_ON_WSA
This file should only be compiled with MANAGEDESENT_ON_WSA
#endif
/// <summary>
/// A fake enumeration to allow compilation on platforms that lack this enumeration.
/// </summary>
public enum SecurityAction
{
/// <summary>
/// A fake enumeration to allow compilation on platforms that lack this enumeration.
/// </summary>
LinkDemand
}
/// <summary>
/// A fake attribute to allow compilation on platforms that lack this attribute.
/// </summary>
//// The real one inherits from System.Security.Permissions.CodeAccessSecurityAttribute.
[SerializableAttribute]
[ComVisibleAttribute(true)]
[AttributeUsageAttribute(
AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Constructor
| AttributeTargets.Method, AllowMultiple = true, Inherited = false)]
internal sealed class SecurityPermissionAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="SecurityPermissionAttribute"/> class.
/// </summary>
/// <param name="action">
/// The action.
/// </param>
public SecurityPermissionAttribute(
SecurityAction action)
{
}
/// <summary>
/// Prints out the object's contents.
/// </summary>
/// <returns>A string represenetation or the object.</returns>
public override string ToString()
{
return base.ToString();
}
}
/// <summary>
/// A fake attribute to allow compilation on platforms that lack this attribute.
/// </summary>
[ComVisibleAttribute(true)]
[AttributeUsageAttribute(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Interface, Inherited = false)]
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass",
Justification = "Reviewed. Suppression is OK here because it's a collection of trivial classes.")]
[SuppressMessage(
"Microsoft.StyleCop.CSharp.MaintainabilityRules",
"SA1402:FileMayOnlyContainASingleClass",
Justification = "These stub classes are compiled only on some platforms that do not contain the entire framework, e.g. new Windows user interface.")]
internal sealed class BestFitMappingAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="BestFitMappingAttribute"/> class.
/// </summary>
/// <param name="bestFitMapping">
/// The best fit mapping.
/// </param>
public BestFitMappingAttribute(
bool bestFitMapping)
{
}
/// <summary>
/// Gets or sets a value indicating whether ThrowOnUnmappableChar.
/// </summary>
public bool ThrowOnUnmappableChar
{
get;
set;
}
/// <summary>
/// Prints out the object's contents.
/// </summary>
/// <returns>A string represenetation or the object.</returns>
public override string ToString()
{
return base.ToString();
}
}
/// <summary>
/// A fake attribute to allow compilation on platforms that lack this attribute.
/// </summary>
[ComVisibleAttribute(true)]
[AttributeUsageAttribute(AttributeTargets.Class | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = true,
Inherited = false)]
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass",
Justification = "Reviewed. Suppression is OK here because it's a collection of trivial classes.")]
[SuppressMessage(
"Microsoft.StyleCop.CSharp.MaintainabilityRules",
"SA1402:FileMayOnlyContainASingleClass",
Justification = "These stub classes are compiled only on some platforms that do not contain the entire framework, e.g. new Windows user interface.")]
internal sealed class SuppressUnmanagedCodeSecurityAttribute : Attribute
{
/// <summary>
/// Prints out the object's contents.
/// </summary>
/// <returns>A string represenetation or the object.</returns>
public override string ToString()
{
return base.ToString();
}
}
/// <summary>
/// A fake attribute to allow compilation on platforms that lack this attribute.
/// </summary>
[AttributeUsageAttribute(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Interface | AttributeTargets.Delegate, Inherited = false)]
[ComVisibleAttribute(true)]
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass",
Justification = "Reviewed. Suppression is OK here because it's a collection of trivial classes.")]
[SuppressMessage(
"Microsoft.StyleCop.CSharp.MaintainabilityRules",
"SA1402:FileMayOnlyContainASingleClass",
Justification = "These stub classes are compiled only on some platforms that do not contain the entire framework, e.g. new Windows user interface.")]
internal sealed class ComVisibleAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="ComVisibleAttribute"/> class.
/// </summary>
/// <param name="comVisible">
/// The com visible.
/// </param>
public ComVisibleAttribute(bool comVisible)
{
}
/// <summary>
/// Prints out the object's contents.
/// </summary>
/// <returns>A string represenetation or the object.</returns>
public override string ToString()
{
return base.ToString();
}
}
/// <summary>
/// Indicates that a class can be serialized. This class cannot be inherited.
/// </summary>
/// <filterpriority>1</filterpriority>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Delegate, Inherited = false), ComVisible(true)]
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass",
Justification = "Reviewed. Suppression is OK here because it's a collection of trivial classes.")]
[SuppressMessage(
"Microsoft.StyleCop.CSharp.MaintainabilityRules",
"SA1402:FileMayOnlyContainASingleClass",
Justification = "These stub classes are compiled only on some platforms that do not contain the entire framework, e.g. new Windows user interface.")]
internal sealed class SerializableAttribute : Attribute
{
/// <summary>
/// Prints out the object's contents.
/// </summary>
/// <returns>A string represenetation or the object.</returns>
public override string ToString()
{
return base.ToString();
}
}
/// <summary>
/// Indicates that a field of a serializable class should not be serialized. This class cannot be inherited.
/// </summary>
/// <filterpriority>1</filterpriority>
[ComVisible(true), AttributeUsage(AttributeTargets.Field, Inherited = false)]
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass",
Justification = "Reviewed. Suppression is OK here because it's a collection of trivial classes.")]
[SuppressMessage(
"Microsoft.StyleCop.CSharp.MaintainabilityRules",
"SA1402:FileMayOnlyContainASingleClass",
Justification = "These stub classes are compiled only on some platforms that do not contain the entire framework, e.g. new Windows user interface.")]
internal sealed class NonSerializedAttribute : Attribute
{
/// <summary>
/// Prints out the object's contents.
/// </summary>
/// <returns>A string represenetation or the object.</returns>
public override string ToString()
{
return base.ToString();
}
}
}
namespace System.Runtime.ConstrainedExecution
{
}
namespace System.Security.Cryptography
{
}
namespace System.Security.Permissions
{
}
namespace Microsoft.Win32.SafeHandles
{
}
namespace System.Runtime.ConstrainedExecution
{
using System;
using Microsoft.Isam.Esent.Interop;
/// <summary>
/// The consistency model. A stub.
/// </summary>
internal enum Consistency
{
/// <summary>
/// Might corrupt the process.
/// </summary>
MayCorruptProcess,
/// <summary>
/// Might corrupt the application domain.
/// </summary>
MayCorruptAppDomain,
/// <summary>
/// Might corrupt the instance.
/// </summary>
MayCorruptInstance,
/// <summary>
/// Will not corrupt the state.
/// </summary>
WillNotCorruptState,
}
/// <summary>
/// The Crticial Execution Region description. A stub.
/// </summary>
internal enum Cer
{
/// <summary>
/// No options.
/// </summary>
None,
/// <summary>
/// This might fail.
/// </summary>
MayFail,
/// <summary>
/// A successful CER.
/// </summary>
Success,
}
/// <summary>
/// The description of the reliability contract. A stub.
/// </summary>
internal sealed class ReliabilityContractAttribute : Attribute
{
/// <summary>
/// The consistency guarantee. A stub.
/// </summary>
private Consistency consistency;
/// <summary>
/// The critical execution region. A stub.
/// </summary>
private Cer cer;
/// <summary>
/// Initializes a new instance of the ReliabilityContractAttribute class. A stub.
/// </summary>
/// <param name="consistencyGuarantee">The guarantee of the consistency.</param>
/// <param name="cer">The critical execution region description.</param>
public ReliabilityContractAttribute(Consistency consistencyGuarantee, Cer cer)
{
this.consistency = consistencyGuarantee;
this.cer = cer;
}
/// <summary>
/// Gets the consistency guarantee. A stub.
/// </summary>
public Consistency ConsistencyGuarantee
{
get
{
return this.consistency;
}
}
/// <summary>
/// Gets the critical execution region. A stub.
/// </summary>
public Cer Cer
{
get
{
return this.cer;
}
}
}
}

View File

@ -1,273 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="EsentStubs.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
// <summary>
// Class stubs to allow compiling on CoreClr.
// </summary>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
/// <summary>
/// Some useful functionality that was omitted from Core CLR classes.
/// </summary>
[SuppressMessage(
"Microsoft.StyleCop.CSharp.MaintainabilityRules",
"SA1402:FileMayOnlyContainASingleClass",
Justification = "These stub classes are compiled only on some platforms that do not contain the entire framework, e.g. new Windows user interface.")]
public static class ExtensionsToCoreClr
{
/// <summary>Converts the value of this instance to the equivalent OLE Automation date.</summary>
/// <param name="dateTime">A DateTime structure.</param>
/// <returns>A double-precision floating-point number that contains an OLE Automation date equivalent to the value of this instance.</returns>
/// <exception cref="T:System.OverflowException">The value of this instance cannot be represented as an OLE Automation Date. </exception>
/// <filterpriority>2</filterpriority>
public static double ToOADate(this DateTime dateTime)
{
return LibraryHelpers.TicksToOADate(dateTime.Ticks);
}
}
/// <summary>
/// JetApi code that is specific to ESENT.
/// </summary>
[SuppressMessage(
"Microsoft.StyleCop.CSharp.MaintainabilityRules",
"SA1402:FileMayOnlyContainASingleClass",
Justification = "These stub classes are compiled only on some platforms that do not contain the entire framework, e.g. new Windows user interface.")]
public class SerializationInfo
{
/// <summary>
/// Prints out the object's contents.
/// </summary>
/// <returns>A string represenetation or the object.</returns>
public override string ToString()
{
return base.ToString();
}
/// <summary>
/// Deserializes an integer.
/// </summary>
/// <param name="propName">The name of the field to retrieve.</param>
/// <returns>An integer.</returns>
public int GetInt32(string propName)
{
return 0;
}
}
/// <summary>
/// A fake class to allow compilation on platforms that lack this class.
/// </summary>
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass",
Justification = "Reviewed. Suppression is OK here because it's a collection of trivial classes.")]
[SuppressMessage(
"Microsoft.StyleCop.CSharp.MaintainabilityRules",
"SA1402:FileMayOnlyContainASingleClass",
Justification = "These stub classes are compiled only on some platforms that do not contain the entire framework, e.g. new Windows user interface.")]
internal static class RuntimeHelpers
{
/// <summary>
/// A fake function to allow compilation on platforms that lack this functionality.
/// </summary>
public static void PrepareConstrainedRegions()
{
}
/// <summary>
/// A fake function to allow compilation on platforms that lack this functionality.
/// </summary>
/// <param name="method">
/// The method.
/// </param>
public static void PrepareMethod(RuntimeMethodHandle method)
{
}
}
/// <summary>
/// A fake class to allow compilation on platforms that lack this class.
/// </summary>
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass",
Justification = "Reviewed. Suppression is OK here because it's a collection of trivial classes.")]
internal class TraceSwitch
{
/// <summary>
/// Initializes a new instance of the <see cref="TraceSwitch"/> class.
/// </summary>
/// <param name="displayName">
/// The display name.
/// </param>
/// <param name="description">
/// The description.
/// </param>
public TraceSwitch(string displayName, string description)
{
}
/// <summary>
/// Gets a value indicating whether TraceVerbose.
/// </summary>
public bool TraceVerbose { get; private set; }
/// <summary>
/// Gets a value indicating whether TraceWarning.
/// </summary>
public bool TraceWarning { get; private set; }
/// <summary>
/// Gets a value indicating whether TraceError.
/// </summary>
public bool TraceError { get; private set; }
/// <summary>
/// Gets a value indicating whether TraceInfo.
/// </summary>
public bool TraceInfo { get; private set; }
/// <summary>
/// Prints out the object's contents.
/// </summary>
/// <returns>A string represenetation or the object.</returns>
public override string ToString()
{
return base.ToString();
}
}
/// <summary>
/// A fake class to allow compilation on platforms that lack this class.
/// </summary>
[SuppressMessage("StyleCop.CSharp.MaintainabilityRules", "SA1402:FileMayOnlyContainASingleClass",
Justification = "Reviewed. Suppression is OK here because it's a collection of trivial classes.")]
internal class Trace
{
/// <summary>
/// A fake function to allow compilation on platforms that lack this functionality.
/// </summary>
/// <param name="condition">
/// The condition.
/// </param>
/// <param name="message">
/// The message.
/// </param>
[ConditionalAttribute("TRACE")]
public static void WriteLineIf(bool condition, string message)
{
}
/// <summary>
/// A fake function to allow compilation on platforms that lack this functionality.
/// </summary>
/// <param name="message">
/// The message.
/// </param>
[ConditionalAttribute("TRACE")]
public static void TraceError(string message)
{
}
/// <summary>
/// A fake function to allow compilation on platforms that lack this functionality.
/// </summary>
/// <param name="message">
/// The message.
/// </param>
/// <param name="args">
/// The arguments.
/// </param>
[ConditionalAttribute("TRACE")]
public static void TraceWarning(string message, params object[] args)
{
}
}
}
#if MANAGEDESENT_ON_WSA
namespace System.ComponentModel
{
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using System.Security;
/// <summary>
/// An exception from a Win32 call.
/// </summary>
//// The original derives from System.Runtime.InteropServices.ExternalException.
internal class Win32Exception : Exception
{
/// <summary>
/// The error code from a Win32 call.
/// </summary>
private readonly int nativeErrorCode;
/// <summary>
/// Initializes a new instance of the Win32Exception class.
/// </summary>
[SecuritySafeCritical]
public Win32Exception() : this(Marshal.GetLastWin32Error())
{
}
/// <summary>
/// Initializes a new instance of the Win32Exception class.
/// </summary>
/// <param name="error">A win32 error code.</param>
[SecuritySafeCritical]
public Win32Exception(int error) : this(error, Win32Exception.GetErrorMessage(error))
{
}
/// <summary>
/// Initializes a new instance of the Win32Exception class.
/// </summary>
/// <param name="error">A win32 error code.</param>
/// <param name="message">The string message.</param>
public Win32Exception(int error, string message)
: base(message)
{
this.nativeErrorCode = error;
}
/// <summary>
/// Initializes a new instance of the Win32Exception class.
/// </summary>
/// <param name="message">The string message.</param>
[SecuritySafeCritical]
public Win32Exception(string message) : this(Marshal.GetLastWin32Error(), message)
{
}
/// <summary>
/// Initializes a new instance of the Win32Exception class.
/// </summary>
/// <param name="message">The string message.</param>
/// <param name="innerException">The nested exception.</param>
[SecuritySafeCritical, SuppressMessage("Microsoft.Interoperability", "CA1404:CallGetLastErrorImmediatelyAfterPInvoke", Justification = "Retuning error codes.")]
public Win32Exception(string message, Exception innerException) : base(message, innerException)
{
this.nativeErrorCode = Marshal.GetLastWin32Error();
}
/// <summary>
/// Returns a string value of the Win32 error code.
/// </summary>
/// <param name="error">The Win32 error code.</param>
/// <returns>A string representation.</returns>
[SecuritySafeCritical]
private static string GetErrorMessage(int error)
{
string result = string.Empty;
result = "Win32 error (0x" + Convert.ToString(error, 16) + ")";
return result;
}
}
}
#endif // MANAGEDESENT_ON_WSA

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.2 KiB

File diff suppressed because it is too large Load Diff

View File

@ -1,76 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="EsentErrorException.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Runtime.Serialization;
/// <summary>
/// Base class for ESENT error exceptions.
/// </summary>
[Serializable]
public class EsentErrorException : EsentException
{
/// <summary>
/// The error code that was encountered.
/// </summary>
private JET_err errorCode;
/// <summary>
/// Initializes a new instance of the EsentErrorException class.
/// </summary>
/// <param name="message">The description of the error.</param>
/// <param name="err">The error code of the exception.</param>
internal EsentErrorException(string message, JET_err err) : base(message)
{
this.errorCode = err;
}
/// <summary>
/// Initializes a new instance of the EsentErrorException class. This constructor
/// is used to deserialize a serialized exception.
/// </summary>
/// <param name="info">The data needed to deserialize the object.</param>
/// <param name="context">The deserialization context.</param>
protected EsentErrorException(SerializationInfo info, StreamingContext context) :
base(info, context)
{
this.errorCode = (JET_err)info.GetInt32("errorCode");
}
/// <summary>
/// Gets the underlying Esent error for this exception.
/// </summary>
public JET_err Error
{
get
{
return this.errorCode;
}
}
#if !MANAGEDESENT_ON_CORECLR // Serialization does not work in Core CLR.
/// <summary>When overridden in a derived class, sets the <see cref="T:System.Runtime.Serialization.SerializationInfo" /> with information about the exception.</summary>
/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo" /> that holds the serialized object data about the exception being thrown. </param>
/// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext" /> that contains contextual information about the source or destination. </param>
/// <exception cref="T:System.ArgumentNullException">The <paramref name="info" /> parameter is a null reference (Nothing in Visual Basic). </exception>
/// <filterpriority>2</filterpriority>
/// <PermissionSet>
/// <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Read="*AllFiles*" PathDiscovery="*AllFiles*" />
/// <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="SerializationFormatter" />
/// </PermissionSet>
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
if (info != null)
{
info.AddValue("errorCode", this.errorCode, typeof(int));
}
}
#endif
}
}

View File

@ -1,51 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="EsentException.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent
{
using System;
using System.Runtime.Serialization;
#if !MANAGEDESENT_SUPPORTS_SERIALIZATION && MANAGEDESENT_ON_WSA
using Microsoft.Isam.Esent.Interop;
using SerializableAttribute = Microsoft.Isam.Esent.Interop.SerializableAttribute;
#endif
/// <summary>
/// Base class for ESENT exceptions.
/// </summary>
[Serializable]
public abstract class EsentException : Exception
{
/// <summary>
/// Initializes a new instance of the EsentException class.
/// </summary>
protected EsentException()
{
}
/// <summary>
/// Initializes a new instance of the EsentException class with a specified error message.
/// </summary>
/// <param name="message">The message that describes the error.</param>
protected EsentException(string message)
: base(message)
{
}
/// <summary>
/// Initializes a new instance of the EsentException class. This constructor
/// is used to deserialize a serialized exception.
/// </summary>
/// <param name="info">The data needed to deserialize the object.</param>
/// <param name="context">The deserialization context.</param>
protected EsentException(SerializationInfo info, StreamingContext context)
#if MANAGEDESENT_SUPPORTS_SERIALIZATION || !MANAGEDESENT_ON_WSA
: base(info, context)
#endif
{
}
}
}

View File

@ -1,109 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{E929E163-52A0-4AAC-917B-6D7FAF70C45E}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Esent.Interop</RootNamespace>
<AssemblyName>Esent.Interop</AssemblyName>
<TargetFrameworks>netstandard2.0</TargetFrameworks>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<DefineConstants></DefineConstants>
<FileAlignment>512</FileAlignment>
<SignAssembly>true</SignAssembly>
<PublicKeyFile>..\scripts\internal\35MSSharedLib1024.snk</PublicKeyFile>
<Platforms>AnyCPU;x86</Platforms>
</PropertyGroup>
<!-- The .snk file won't be published to codeplex. -->
<PropertyGroup Condition="Exists('$(PublicKeyFile)')">
<DefineConstants>$(DefineConstants);STRONG_NAMED</DefineConstants>
<DelaySign>true</DelaySign>
<AssemblyOriginatorKeyFile>$(PublicKeyFile)</AssemblyOriginatorKeyFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>$(DefineConstants);DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
<DocumentationFile>$(OutputPath)\$(AssemblyName).xml</DocumentationFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>$(DefineConstants);DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
<DocumentationFile>$(OutputPath)\$(AssemblyName).xml</DocumentationFile>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<DocumentationFile>$(OutputPath)\$(AssemblyName).xml</DocumentationFile>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>$(DefineConstants)</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<DocumentationFile>$(OutputPath)\$(AssemblyName).xml</DocumentationFile>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
<CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
<Prefer32Bit>false</Prefer32Bit>
</PropertyGroup>
<ItemGroup>
<Compile Include="*.cs" />
<Compile Include="Esent\CallbackDataConverter.cs" />
<Compile Include="Esent\EsentJetApi.cs" />
<Compile Include="Esent\EsentNativeMethods.cs" />
<Compile Include="Esent\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="Properties\" />
</ItemGroup>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -1,50 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="EsentInvalidColumnException.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Runtime.Serialization;
/// <summary>
/// Exception thrown when a column conversion fails.
/// </summary>
[Serializable]
public class EsentInvalidColumnException : EsentException
{
/// <summary>
/// Initializes a new instance of the EsentInvalidColumnException class.
/// </summary>
public EsentInvalidColumnException()
{
}
#if MANAGEDESENT_ON_CORECLR
#else
/// <summary>
/// Initializes a new instance of the EsentInvalidColumnException class. This constructor
/// is used to deserialize a serialized exception.
/// </summary>
/// <param name="info">The data needed to deserialize the object.</param>
/// <param name="context">The deserialization context.</param>
protected EsentInvalidColumnException(SerializationInfo info, StreamingContext context) :
base(info, context)
{
}
#endif
/// <summary>
/// Gets a text message describing the exception.
/// </summary>
public override string Message
{
get
{
return "Column is not valid for this operation";
}
}
}
}

View File

@ -1,127 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="EsentResource.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
/// <summary>
/// This is the base class for all esent resource objects.
/// Subclasses of this class can allocate and release unmanaged
/// resources.
/// </summary>
public abstract class EsentResource : IDisposable
{
/// <summary>
/// True if a resource has been allocated.
/// </summary>
private bool hasResource;
/// <summary>
/// True if this object has been disposed.
/// </summary>
private bool isDisposed;
/// <summary>
/// Finalizes an instance of the EsentResource class.
/// </summary>
~EsentResource()
{
this.Dispose(false);
}
/// <summary>
/// Gets a value indicating whether the underlying resource
/// is currently allocated.
/// </summary>
protected bool HasResource
{
get
{
return this.hasResource;
}
}
/// <summary>
/// Dispose of this object, releasing the underlying
/// Esent resource.
/// </summary>
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Called by Dispose and the finalizer.
/// </summary>
/// <param name="isDisposing">
/// True if called from Dispose.
/// </param>
protected virtual void Dispose(bool isDisposing)
{
if (isDisposing)
{
if (this.hasResource)
{
this.ReleaseResource();
Debug.Assert(!this.hasResource, "Resource was not freed");
}
this.isDisposed = true;
}
else
{
if (this.hasResource)
{
// We should not get to this point. The problem is that if
// we use finalizers to free esent resources they may end
// up being freed in the wrong order (e.g. JetEndSession is
// called before JetCloseTable). Freeing esent resources
// in the wrong order will generate EsentExceptions.
Trace.TraceWarning("Non-finalized ESENT resource {0}", this);
}
}
}
/// <summary>
/// Throw an exception if this object has been disposed.
/// </summary>
protected void CheckObjectIsNotDisposed()
{
if (this.isDisposed)
{
throw new ObjectDisposedException("EsentResource");
}
}
/// <summary>
/// Called by a subclass when a resource is allocated.
/// </summary>
protected void ResourceWasAllocated()
{
this.CheckObjectIsNotDisposed();
Debug.Assert(!this.hasResource, "Resource is already allocated");
this.hasResource = true;
}
/// <summary>
/// Called by a subclass when a resource is freed.
/// </summary>
protected void ResourceWasReleased()
{
Debug.Assert(this.hasResource, "Resource is not allocated");
this.CheckObjectIsNotDisposed();
this.hasResource = false;
}
/// <summary>
/// Implemented by the subclass to release a resource.
/// </summary>
protected abstract void ReleaseResource();
}
}

View File

@ -1,113 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="EsentStopwatch.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
using Microsoft.Isam.Esent.Interop.Vista;
/// <summary>
/// Provides a set of methods and properties that you can use to measure
/// ESENT work statistics for a thread. If the current version of ESENT
/// doesn't support <see cref="VistaApi.JetGetThreadStats"/> then all
/// ESENT statistics will be 0.
/// </summary>
public class EsentStopwatch
{
/// <summary>
/// Used to measure how long statistics are collected for.
/// </summary>
private Stopwatch stopwatch;
/// <summary>
/// The stats at the start of our collection.
/// </summary>
private JET_THREADSTATS statsAtStart;
/// <summary>
/// Gets a value indicating whether the EsentStopwatch timer is running.
/// </summary>
public bool IsRunning { get; private set; }
/// <summary>
/// Gets the total ESENT work stats measured by the current instance.
/// </summary>
public JET_THREADSTATS ThreadStats { get; private set; }
/// <summary>
/// Gets the total elapsed time measured by the current instance.
/// </summary>
public TimeSpan Elapsed { get; private set; }
/// <summary>
/// Initializes a new EsentStopwatch instance and starts
/// measuring elapsed time.
/// </summary>
/// <returns>A new, running EsentStopwatch.</returns>
public static EsentStopwatch StartNew()
{
var stopwatch = new EsentStopwatch();
stopwatch.Start();
return stopwatch;
}
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="Stopwatch"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="Stopwatch"/>.
/// </returns>
public override string ToString()
{
return this.IsRunning ? "EsentStopwatch (running)" : this.Elapsed.ToString();
}
/// <summary>
/// Starts measuring ESENT work.
/// </summary>
public void Start()
{
this.Reset();
this.stopwatch = Stopwatch.StartNew();
this.IsRunning = true;
if (EsentVersion.SupportsVistaFeatures)
{
VistaApi.JetGetThreadStats(out this.statsAtStart);
}
}
/// <summary>
/// Stops measuring ESENT work.
/// </summary>
public void Stop()
{
if (this.IsRunning)
{
this.IsRunning = false;
this.stopwatch.Stop();
this.Elapsed = this.stopwatch.Elapsed;
if (EsentVersion.SupportsVistaFeatures)
{
JET_THREADSTATS statsAtEnd;
VistaApi.JetGetThreadStats(out statsAtEnd);
this.ThreadStats = statsAtEnd - this.statsAtStart;
}
}
}
/// <summary>
/// Stops time interval measurement and resets the thread statistics.
/// </summary>
public void Reset()
{
this.stopwatch = null;
this.ThreadStats = new JET_THREADSTATS();
this.Elapsed = TimeSpan.Zero;
this.IsRunning = false;
}
}
}

View File

@ -1,134 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="EsentVersion.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using Microsoft.Isam.Esent.Interop.Implementation;
/// <summary>
/// Gives information about the version of esent being used.
/// </summary>
public static class EsentVersion
{
/// <summary>
/// Gets a value indicating whether the current version of esent
/// supports features available in the Windows Server 2003 version of
/// esent.
/// </summary>
public static bool SupportsServer2003Features
{
get
{
return Capabilities.SupportsServer2003Features;
}
}
/// <summary>
/// Gets a value indicating whether the current version of esent
/// supports features available in the Windows Vista version of
/// esent.
/// </summary>
public static bool SupportsVistaFeatures
{
get
{
return Capabilities.SupportsVistaFeatures;
}
}
/// <summary>
/// Gets a value indicating whether the current version of esent
/// supports features available in the Windows 7 version of
/// esent.
/// </summary>
public static bool SupportsWindows7Features
{
get
{
return Capabilities.SupportsWindows7Features;
}
}
/// <summary>
/// Gets a value indicating whether the current version of esent
/// supports features available in the Windows 8 version of
/// esent.
/// </summary>
public static bool SupportsWindows8Features
{
get
{
return Capabilities.SupportsWindows8Features;
}
}
/// <summary>
/// Gets a value indicating whether the current version of esent
/// supports features available in the Windows 8.1 version of
/// esent.
/// </summary>
public static bool SupportsWindows81Features
{
get
{
return Capabilities.SupportsWindows81Features;
}
}
/// <summary>
/// Gets a value indicating whether the current version of esent
/// supports features available in the Windows 10 version of
/// esent.
/// </summary>
public static bool SupportsWindows10Features
{
get
{
return Capabilities.SupportsWindows10Features;
}
}
/// <summary>
/// Gets a value indicating whether the current version of esent
/// can use non-ASCII paths to access databases.
/// </summary>
public static bool SupportsUnicodePaths
{
get
{
return Capabilities.SupportsUnicodePaths;
}
}
/// <summary>
/// Gets a value indicating whether large (> 255 byte) keys are supported.
/// The key size for an index can be specified in the <see cref="JET_INDEXCREATE"/>
/// object.
/// </summary>
public static bool SupportsLargeKeys
{
get
{
return Capabilities.SupportsLargeKeys;
}
}
/// <summary>
/// Gets a description of the current Esent capabilities.
/// </summary>
/// <remarks>
/// We allow this to be set separately so that capabilities can
/// be downgraded for testing.
/// </remarks>
private static JetCapabilities Capabilities
{
get
{
return Api.Impl.Capabilities;
}
}
}
}

View File

@ -1,69 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="FloatColumnValue.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
/// <summary>
/// A <see cref="float"/> column value.
/// </summary>
public class FloatColumnValue : ColumnValueOfStruct<float>
{
/// <summary>
/// Gets the size of the value in the column. This returns 0 for
/// variable sized columns (i.e. binary and string).
/// </summary>
protected override int Size
{
[DebuggerStepThrough]
get { return sizeof(float); }
}
/// <summary>
/// Recursive SetColumns method for data pinning. This populates the buffer and
/// calls the inherited SetColumns method.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to set the columns in. An update should be prepared.
/// </param>
/// <param name="columnValues">
/// Column values to set.
/// </param>
/// <param name="nativeColumns">
/// Structures to put the pinned data in.
/// </param>
/// <param name="i">Offset of this object in the array.</param>
/// <returns>An error code.</returns>
internal override unsafe int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i)
{
var data = this.Value.GetValueOrDefault();
return this.SetColumns(sesid, tableid, columnValues, nativeColumns, i, &data, sizeof(float), this.Value.HasValue);
}
/// <summary>
/// Given data retrieved from ESENT, decode the data and set the value in the ColumnValue object.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within the bytes.</param>
/// <param name="count">The number of bytes to decode.</param>
/// <param name="err">The error returned from ESENT.</param>
protected override void GetValueFromBytes(byte[] value, int startIndex, int count, int err)
{
if (JET_wrn.ColumnNull == (JET_wrn)err)
{
this.Value = null;
}
else
{
this.CheckDataCount(count);
this.Value = BitConverter.ToSingle(value, startIndex);
}
}
}
}

View File

@ -1,94 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="GCHandleCollection.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop.Implementation
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
/// <summary>
/// A collection of GCHandles for pinned objects. The handles
/// are freed when this object is disposed.
/// </summary>
[StructLayout(LayoutKind.Auto)]
internal struct GCHandleCollection : IDisposable
{
/// <summary>
/// The handles of the objects being pinned.
/// </summary>
private GCHandle[] handles;
/// <summary>
/// Handle count.
/// </summary>
private int count;
/// <summary>
/// Disposes of the object.
/// </summary>
public void Dispose()
{
if (null != this.handles)
{
for (int i = 0; i < this.count; i++)
{
this.handles[i].Free();
}
this.handles = null;
}
}
/// <summary>
/// Add an object to the handle collection. This automatically
/// pins the object.
/// </summary>
/// <param name="value">The object to pin.</param>
/// <returns>
/// The address of the pinned object. This is valid until the
/// GCHandleCollection is disposed.
/// </returns>
public IntPtr Add(object value)
{
if (null == value)
{
return IntPtr.Zero;
}
if (null == this.handles)
{
this.handles = new GCHandle[4]; // same as List<T>
}
else if (this.count == this.handles.Length)
{
Array.Resize(ref this.handles, this.count * 2);
}
Debug.Assert(this.count < this.handles.Length, "Index out of bound");
GCHandle handle = GCHandle.Alloc(value, GCHandleType.Pinned);
this.handles[this.count++] = handle;
IntPtr pinned = handle.AddrOfPinnedObject();
Debug.Assert(IntPtr.Zero != pinned, "Pinned object has null address");
return pinned;
}
/// <summary>
/// Set handle array capacity.
/// </summary>
/// <param name="capacity">Estimated handle count</param>
public void SetCapacity(int capacity)
{
if (null == this.handles)
{
this.handles = new GCHandle[capacity];
}
}
}
}

View File

@ -1,64 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="GenericEnumerable.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System.Collections;
using System.Collections.Generic;
/// <summary>
/// IEnumerable class that takes a delegate to create the enumerator it returns.
/// </summary>
/// <typeparam name="T">The type returned by the enumerator.</typeparam>
internal class GenericEnumerable<T> : IEnumerable<T>
{
/// <summary>
/// The delegate used to create the enumerator.
/// </summary>
private readonly CreateEnumerator enumeratorCreator;
/// <summary>
/// Initializes a new instance of the <see cref="GenericEnumerable{T}"/> class.
/// </summary>
/// <param name="enumeratorCreator">
/// The enumerator creator.
/// </param>
public GenericEnumerable(CreateEnumerator enumeratorCreator)
{
this.enumeratorCreator = enumeratorCreator;
}
/// <summary>
/// IEnumerator creating delegate.
/// </summary>
/// <returns>A new enumerator.</returns>
public delegate IEnumerator<T> CreateEnumerator();
/// <summary>
/// Returns an enumerator that iterates through the collection.
/// </summary>
/// <returns>
/// A <see cref="T:System.Collections.Generic.IEnumerator`1"/>
/// that can be used to iterate through the collection.
/// </returns>
public IEnumerator<T> GetEnumerator()
{
return this.enumeratorCreator();
}
/// <summary>
/// Returns an enumerator that iterates through a collection.
/// </summary>
/// <returns>
/// A <see cref="T:System.Collections.IEnumerator"/>
/// object that can be used to iterate through the collection.
/// </returns>
IEnumerator IEnumerable.GetEnumerator()
{
return this.GetEnumerator();
}
}
}

View File

@ -1,48 +0,0 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="GetLockHelpers.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
// <summary>
// Helper methods for JetMakeKey.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
#if !MANAGEDESENT_ON_WSA // Not exposed in MSDK
namespace Microsoft.Isam.Esent.Interop
{
using System.Diagnostics;
/// <summary>
/// Helper methods for the ESENT API. These wrap JetMakeKey.
/// </summary>
public static partial class Api
{
/// <summary>
/// Explicitly reserve the ability to update a row, write lock, or to explicitly prevent a row from
/// being updated by any other session, read lock. Normally, row write locks are acquired implicitly as a
/// result of updating rows. Read locks are usually not required because of record versioning. However,
/// in some cases a transaction may desire to explicitly lock a row to enforce serialization, or to ensure
/// that a subsequent operation will succeed.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to use. A lock will be acquired on the current record.</param>
/// <param name="grbit">Lock options, use this to specify which type of lock to obtain.</param>
/// <returns>
/// True if the lock was obtained, false otherwise. An exception is thrown if an unexpected
/// error is encountered.
/// </returns>
public static bool TryGetLock(JET_SESID sesid, JET_TABLEID tableid, GetLockGrbit grbit)
{
var err = (JET_err)Impl.JetGetLock(sesid, tableid, grbit);
if (JET_err.WriteConflict == err)
{
return false;
}
Api.Check((int)err);
Debug.Assert(err >= JET_err.Success, "Exception should have been thrown in case of error");
return true;
}
}
}
#endif // !MANAGEDESENT_ON_WSA

View File

@ -1,82 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="GuidColumnValue.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
/// <summary>
/// A <see cref="Guid"/> column value.
/// </summary>
public class GuidColumnValue : ColumnValueOfStruct<Guid>
{
/// <summary>
/// Gets the size of the value in the column. This returns 0 for
/// variable sized columns (i.e. binary and string).
/// </summary>
protected override int Size
{
[DebuggerStepThrough]
get { return 16; /* sizeof(Guid) */ }
}
/// <summary>
/// Recursive SetColumns method for data pinning. This populates the buffer and
/// calls the inherited SetColumns method.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to set the columns in. An update should be prepared.
/// </param>
/// <param name="columnValues">
/// Column values to set.
/// </param>
/// <param name="nativeColumns">
/// Structures to put the pinned data in.
/// </param>
/// <param name="i">Offset of this object in the array.</param>
/// <returns>An error code.</returns>
internal override unsafe int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i)
{
Guid data = this.Value.GetValueOrDefault();
return this.SetColumns(sesid, tableid, columnValues, nativeColumns, i, &data, this.Size, this.Value.HasValue);
}
/// <summary>
/// Given data retrieved from ESENT, decode the data and set the value in the ColumnValue object.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within the bytes.</param>
/// <param name="count">The number of bytes to decode.</param>
/// <param name="err">The error returned from ESENT.</param>
protected override void GetValueFromBytes(byte[] value, int startIndex, int count, int err)
{
if (JET_wrn.ColumnNull == (JET_wrn)err)
{
this.Value = null;
}
else
{
this.CheckDataCount(count);
unsafe
{
// There isn't a convenient Guid constructor for this case, so
// we copy the data manually.
Guid guid;
void* guidBuffer = &guid;
byte* buffer = (byte*)guidBuffer;
for (int i = 0; i < this.Size; ++i)
{
buffer[i] = value[startIndex + i];
}
this.Value = guid;
}
}
}
}
}

View File

@ -1,26 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="IContentEquatable.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
/// <summary>
/// Interface for objects that can have their contents compared against
/// each other. This should be used for equality comparisons on mutable
/// reference objects where overriding Equals() and GetHashCode() isn't a
/// good idea.
/// </summary>
/// <typeparam name="T">The type of objects to compare.</typeparam>
public interface IContentEquatable<T>
{
/// <summary>
/// Returns a value indicating whether this instance is equal
/// to another instance.
/// </summary>
/// <param name="other">An instance to compare with this instance.</param>
/// <returns>True if the two instances are equal.</returns>
bool ContentEquals(T other);
}
}

View File

@ -1,22 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="IDeepCloneable.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
/// <summary>
/// Interface for objects that can be cloned. This creates a deep copy of
/// the object. It is used for cloning meta-data objects.
/// </summary>
/// <typeparam name="T">The type of object.</typeparam>
public interface IDeepCloneable<T>
{
/// <summary>
/// Returns a deep copy of the object.
/// </summary>
/// <returns>A deep copy of the object.</returns>
T DeepClone();
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="INullableJetStruct.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
/// <summary>
/// Interface for Jet structures that are nullable (can have null values).
/// </summary>
public interface INullableJetStruct
{
/// <summary>
/// Gets a value indicating whether the structure has a null value.
/// </summary>
bool HasValue { get; }
}
}

View File

@ -1,189 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="IndexInfo.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Globalization;
using System.Text;
/// <summary>
/// Information about one esent index. This is not an interop
/// class, but is used by the meta-data helper methods.
/// </summary>
[Serializable]
public class IndexInfo
{
/// <summary>
/// The name of the index.
/// </summary>
private readonly string name;
/// <summary>
/// The culture info of the index.
/// </summary>
private readonly CultureInfo cultureInfo;
/// <summary>
/// Index comparison options.
/// </summary>
private readonly CompareOptions compareOptions;
/// <summary>
/// Index segments.
/// </summary>
private readonly ReadOnlyCollection<IndexSegment> indexSegments;
/// <summary>
/// Index options.
/// </summary>
private readonly CreateIndexGrbit grbit;
/// <summary>
/// Number of unique keys in the index.
/// </summary>
private readonly int keys;
/// <summary>
/// Number of entries in the index.
/// </summary>
private readonly int entries;
/// <summary>
/// Number of pages in the index.
/// </summary>
private readonly int pages;
/// <summary>
/// Initializes a new instance of the IndexInfo class.
/// </summary>
/// <param name="name">Name of the index.</param>
/// <param name="cultureInfo">CultureInfo for string sorting.</param>
/// <param name="compareOptions">String comparison options.</param>
/// <param name="indexSegments">Array of index segment descriptions.</param>
/// <param name="grbit">Index options.</param>
/// <param name="keys">Number of unique keys in the index.</param>
/// <param name="entries">Number of entries in the index.</param>
/// <param name="pages">Number of pages in the index.</param>
internal IndexInfo(
string name,
CultureInfo cultureInfo,
CompareOptions compareOptions,
IndexSegment[] indexSegments,
CreateIndexGrbit grbit,
int keys,
int entries,
int pages)
{
this.name = name;
this.cultureInfo = cultureInfo;
this.compareOptions = compareOptions;
this.indexSegments = new ReadOnlyCollection<IndexSegment>(indexSegments);
this.grbit = grbit;
this.keys = keys;
this.entries = entries;
this.pages = pages;
}
/// <summary>
/// Gets the name of the index.
/// </summary>
public string Name
{
[DebuggerStepThrough]
get { return this.name; }
}
/// <summary>
/// Gets the CultureInfo the index is sorted by.
/// </summary>
public CultureInfo CultureInfo
{
[DebuggerStepThrough]
get { return this.cultureInfo; }
}
/// <summary>
/// Gets the CompareOptions for the index.
/// </summary>
public CompareOptions CompareOptions
{
[DebuggerStepThrough]
get { return this.compareOptions; }
}
/// <summary>
/// Gets the segments of the index.
/// </summary>
public IList<IndexSegment> IndexSegments
{
[DebuggerStepThrough]
get { return this.indexSegments; }
}
/// <summary>
/// Gets the index options.
/// </summary>
public CreateIndexGrbit Grbit
{
[DebuggerStepThrough]
get { return this.grbit; }
}
/// <summary>
/// Gets the number of unique keys in the index.
/// This value is not current and is only is updated by Api.JetComputeStats.
/// </summary>
public int Keys
{
[DebuggerStepThrough]
get { return this.keys; }
}
/// <summary>
/// Gets the number of entries in the index.
/// This value is not current and is only is updated by Api.JetComputeStats.
/// </summary>
public int Entries
{
[DebuggerStepThrough]
get { return this.entries; }
}
/// <summary>
/// Gets the number of pages in the index.
/// This value is not current and is only is updated by Api.JetComputeStats.
/// </summary>
public int Pages
{
[DebuggerStepThrough]
get { return this.pages; }
}
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="IndexInfo"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="IndexInfo"/>.
/// </returns>
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append(this.Name);
sb.Append(" (");
foreach (var segment in this.IndexSegments)
{
sb.Append(segment.ToString());
}
sb.Append(")");
return sb.ToString();
}
}
}

View File

@ -1,153 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="IndexInfoEnumerator.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System.Diagnostics;
using System.Globalization;
using System.Text;
using Microsoft.Isam.Esent.Interop.Windows8;
/// <summary>
/// Base class for enumerators that return IndexInfo objects. Subclasses differ
/// by how they open the table.
/// </summary>
internal abstract class IndexInfoEnumerator : TableEnumerator<IndexInfo>
{
/// <summary>
/// Initializes a new instance of the <see cref="IndexInfoEnumerator"/> class.
/// </summary>
/// <param name="sesid">
/// The session to use.
/// </param>
protected IndexInfoEnumerator(JET_SESID sesid) : base(sesid)
{
}
/// <summary>
/// Gets or sets the indexlist used to retrieve data.
/// </summary>
protected JET_INDEXLIST Indexlist { get; set; }
/// <summary>
/// Gets the entry the cursor is currently positioned on.
/// </summary>
/// <returns>The entry the cursor is currently positioned on.</returns>
protected override IndexInfo GetCurrent()
{
return this.GetIndexInfoFromIndexlist(this.Sesid, this.Indexlist);
}
/// <summary>
/// Retrieves information about indexes on a table.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="indexname">The name of the index.</param>
/// <param name="result">Filled in with information about indexes on the table.</param>
/// <param name="infoLevel">The type of information to retrieve.</param>
protected abstract void GetIndexInfo(
JET_SESID sesid,
string indexname,
out string result,
JET_IdxInfo infoLevel);
/// <summary>
/// Create an array of IndexSegment objects from the data in the current JET_INDEXLIST entry.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="indexlist">The indexlist to take the data from.</param>
/// <returns>An array of IndexSegment objects containing the information for the current index.</returns>
private static IndexSegment[] GetIndexSegmentsFromIndexlist(JET_SESID sesid, JET_INDEXLIST indexlist)
{
var numSegments = (int)Api.RetrieveColumnAsInt32(sesid, indexlist.tableid, indexlist.columnidcColumn);
Debug.Assert(numSegments > 0, "Index has zero index segments");
// If we use the wide API (Vista+), then the temp table will be in UTF-16.
Encoding encodingOfTextColumns = EsentVersion.SupportsVistaFeatures ? Encoding.Unicode : LibraryHelpers.EncodingASCII;
var segments = new IndexSegment[numSegments];
for (int i = 0; i < numSegments; ++i)
{
string columnName = Api.RetrieveColumnAsString(
sesid,
indexlist.tableid,
indexlist.columnidcolumnname,
encodingOfTextColumns,
RetrieveColumnGrbit.None);
columnName = StringCache.TryToIntern(columnName);
var coltyp = (JET_coltyp)Api.RetrieveColumnAsInt32(sesid, indexlist.tableid, indexlist.columnidcoltyp);
var grbit =
(IndexKeyGrbit)Api.RetrieveColumnAsInt32(sesid, indexlist.tableid, indexlist.columnidgrbitColumn);
bool isAscending = IndexKeyGrbit.Ascending == grbit;
var cp = (JET_CP)Api.RetrieveColumnAsInt16(sesid, indexlist.tableid, indexlist.columnidCp);
bool isASCII = JET_CP.ASCII == cp;
segments[i] = new IndexSegment(columnName, coltyp, isAscending, isASCII);
if (i < numSegments - 1)
{
Api.JetMove(sesid, indexlist.tableid, JET_Move.Next, MoveGrbit.None);
}
}
return segments;
}
/// <summary>
/// Create an IndexInfo object from the data in the current JET_INDEXLIST entry.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="indexlist">The indexlist to take the data from.</param>
/// <returns>An IndexInfo object containing the information from that record.</returns>
private IndexInfo GetIndexInfoFromIndexlist(JET_SESID sesid, JET_INDEXLIST indexlist)
{
// If we use the wide API (Vista+), then the temp table will be in UTF-16.
Encoding encodingOfTextColumns = EsentVersion.SupportsVistaFeatures ? Encoding.Unicode : LibraryHelpers.EncodingASCII;
string name = Api.RetrieveColumnAsString(
sesid, indexlist.tableid, indexlist.columnidindexname, encodingOfTextColumns, RetrieveColumnGrbit.None);
name = StringCache.TryToIntern(name);
CultureInfo cultureInfo = null;
if (EsentVersion.SupportsWindows8Features)
{
string localeName;
this.GetIndexInfo(sesid, name, out localeName, Windows8IdxInfo.LocaleName);
cultureInfo = new CultureInfo(localeName);
}
else
{
#if !MANAGEDESENT_ON_CORECLR
// This probably won't work on platforms that don't support LCIDs. Newer environments have dropped
// LCIDs in favour of locale names. But currently JET_INDEXLIST doesn't expose columnidLocale.
int lcid = (int)Api.RetrieveColumnAsInt16(sesid, indexlist.tableid, indexlist.columnidLangid);
cultureInfo = LibraryHelpers.CreateCultureInfoByLcid(lcid);
#endif // !MANAGEDESENT_ON_CORECLR
}
uint lcmapFlags = (uint)Api.RetrieveColumnAsUInt32(sesid, indexlist.tableid, indexlist.columnidLCMapFlags);
CompareOptions compareOptions = Conversions.CompareOptionsFromLCMapFlags(lcmapFlags);
uint grbit = (uint)Api.RetrieveColumnAsUInt32(sesid, indexlist.tableid, indexlist.columnidgrbitIndex);
int keys = (int)Api.RetrieveColumnAsInt32(sesid, indexlist.tableid, indexlist.columnidcKey);
int entries = (int)Api.RetrieveColumnAsInt32(sesid, indexlist.tableid, indexlist.columnidcEntry);
int pages = (int)Api.RetrieveColumnAsInt32(sesid, indexlist.tableid, indexlist.columnidcPage);
IndexSegment[] segments = GetIndexSegmentsFromIndexlist(sesid, indexlist);
return new IndexInfo(
name,
cultureInfo,
compareOptions,
segments,
(CreateIndexGrbit)grbit,
keys,
entries,
pages);
}
}
}

View File

@ -1,152 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="IndexSegment.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
using System.Globalization;
/// <summary>
/// Describes one segment of an index.
/// </summary>
[Serializable]
public class IndexSegment : IEquatable<IndexSegment>
{
/// <summary>
/// The name of the column.
/// </summary>
private readonly string columnName;
/// <summary>
/// The type of the column.
/// </summary>
private readonly JET_coltyp coltyp;
/// <summary>
/// True if the column is sorted in ascending order.
/// </summary>
private readonly bool isAscending;
/// <summary>
/// True if the column is an ASCII column.
/// </summary>
private readonly bool isASCII;
/// <summary>
/// Initializes a new instance of the IndexSegment class.
/// </summary>
/// <param name="name">The name of the indexed column.</param>
/// <param name="coltyp">The type of the column.</param>
/// <param name="isAscending">True if the column is ascending.</param>
/// <param name="isASCII">True if the column is over an ASCII column.</param>
internal IndexSegment(
string name,
JET_coltyp coltyp,
bool isAscending,
bool isASCII)
{
this.columnName = name;
this.coltyp = coltyp;
this.isAscending = isAscending;
this.isASCII = isASCII;
}
/// <summary>
/// Gets name of the column being indexed.
/// </summary>
public string ColumnName
{
[DebuggerStepThrough]
get { return this.columnName; }
}
/// <summary>
/// Gets the type of the column being indexed.
/// </summary>
public JET_coltyp Coltyp
{
[DebuggerStepThrough]
get { return this.coltyp; }
}
/// <summary>
/// Gets a value indicating whether the index segment is ascending.
/// </summary>
public bool IsAscending
{
[DebuggerStepThrough]
get { return this.isAscending; }
}
/// <summary>
/// Gets a value indicating whether the index segment is over an ASCII text
/// column. This value is only meaningful for text column segments.
/// </summary>
public bool IsASCII
{
[DebuggerStepThrough]
get { return this.isASCII; }
}
/// <summary>
/// Returns a value indicating whether this instance is equal
/// to another instance.
/// </summary>
/// <param name="obj">An object to compare with this instance.</param>
/// <returns>True if the two instances are equal.</returns>
public override bool Equals(object obj)
{
if (obj == null || this.GetType() != obj.GetType())
{
return false;
}
return this.Equals((IndexSegment)obj);
}
/// <summary>
/// Generate a string representation of the instance.
/// </summary>
/// <returns>The structure as a string.</returns>
public override string ToString()
{
return string.Format(
CultureInfo.InvariantCulture, "{0}{1}({2})", this.isAscending ? "+" : "-", this.columnName, this.coltyp);
}
/// <summary>
/// Returns the hash code for this instance.
/// </summary>
/// <returns>The hash code for this instance.</returns>
public override int GetHashCode()
{
return this.columnName.GetHashCode()
^ (int)this.coltyp * 31
^ (this.isAscending ? 0x10000 : 0x20000)
^ (this.isASCII ? 0x40000 : 0x80000);
}
/// <summary>
/// Returns a value indicating whether this instance is equal
/// to another instance.
/// </summary>
/// <param name="other">An instance to compare with this instance.</param>
/// <returns>True if the two instances are equal.</returns>
public bool Equals(IndexSegment other)
{
if (null == other)
{
return false;
}
return this.columnName.Equals(other.columnName, StringComparison.OrdinalIgnoreCase)
&& this.coltyp == other.coltyp
&& this.isAscending == other.isAscending
&& this.isASCII == other.isASCII;
}
}
}

View File

@ -1,337 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="Instance.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.CompilerServices;
using System.Security.Permissions;
using Microsoft.Isam.Esent.Interop.Vista;
using Microsoft.Win32.SafeHandles;
/// <summary>
/// A class that encapsulates a <see cref="JET_INSTANCE"/> in a disposable object. The
/// instance must be closed last and closing the instance releases all other
/// resources for the instance.
/// </summary>
public class Instance : SafeHandleZeroOrMinusOneIsInvalid
{
/// <summary>
/// Parameters for the instance.
/// </summary>
private readonly InstanceParameters parameters;
/// <summary>
/// The name of the instance.
/// </summary>
private readonly string name;
/// <summary>
/// The display name of the instance.
/// </summary>
private readonly string displayName;
/// <summary>
/// The TermGrbit to be used at JetTerm time.
/// </summary>
private TermGrbit termGrbit;
/// <summary>
/// Initializes a new instance of the Instance class. The underlying
/// JET_INSTANCE is allocated, but not initialized.
/// </summary>
/// <param name="name">
/// The name of the instance. This string must be unique within a
/// given process hosting the database engine.
/// </param>
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
public Instance(string name) : this(name, name, TermGrbit.None)
{
}
/// <summary>
/// Initializes a new instance of the Instance class. The underlying
/// JET_INSTANCE is allocated, but not initialized.
/// </summary>
/// <param name="name">
/// The name of the instance. This string must be unique within a
/// given process hosting the database engine.
/// </param>
/// <param name="displayName">
/// A display name for the instance. This will be used in eventlog
/// entries.
/// </param>
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
public Instance(string name, string displayName) : this(name, displayName, TermGrbit.None)
{
}
/// <summary>
/// Initializes a new instance of the Instance class. The underlying
/// JET_INSTANCE is allocated, but not initialized.
/// </summary>
/// <param name="name">
/// The name of the instance. This string must be unique within a
/// given process hosting the database engine.
/// </param>
/// <param name="displayName">
/// A display name for the instance. This will be used in eventlog
/// entries.
/// </param>
/// <param name="termGrbit">
/// The TermGrbit to be used at JetTerm time.
/// </param>
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
public Instance(string name, string displayName, TermGrbit termGrbit) : base(true)
{
this.name = name;
this.displayName = displayName;
this.termGrbit = termGrbit;
JET_INSTANCE instance;
RuntimeHelpers.PrepareConstrainedRegions();
try
{
this.SetHandle(JET_INSTANCE.Nil.Value);
}
finally
{
// This is the code that we want in a constrained execution region.
// We need to avoid the situation where JetCreateInstance2 is called
// but the handle isn't set, so the instance is never terminated.
// This would happen, for example, if there was a ThreadAbortException
// between the call to JetCreateInstance2 and the call to SetHandle.
//
// If an Esent exception is generated we do not want to call SetHandle
// because the instance isn't valid. On the other hand if a different
// exception (out of memory or thread abort) is generated we still need
// to set the handle to avoid losing track of the instance. The call to
// JetCreateInstance2 is in the CER to make sure that the only exceptions
// which can be generated are from ESENT failures.
Api.JetCreateInstance2(out instance, this.name, this.displayName, CreateInstanceGrbit.None);
this.SetHandle(instance.Value);
}
this.parameters = new InstanceParameters(instance);
}
/// <summary>
/// Gets the JET_INSTANCE that this instance contains.
/// </summary>
public JET_INSTANCE JetInstance
{
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
get
{
this.CheckObjectIsNotDisposed();
return this.CreateInstanceFromHandle();
}
}
/// <summary>
/// Gets the InstanceParameters for this instance.
/// </summary>
public InstanceParameters Parameters
{
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
get
{
this.CheckObjectIsNotDisposed();
return this.parameters;
}
}
/// <summary>
/// Gets or sets the TermGrbit for this instance.
/// </summary>
public TermGrbit TermGrbit
{
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
get
{
this.CheckObjectIsNotDisposed();
return this.termGrbit;
}
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
set
{
this.CheckObjectIsNotDisposed();
this.termGrbit = value;
}
}
/// <summary>
/// Provide implicit conversion of an Instance object to a JET_INSTANCE
/// structure. This is done so that an Instance can be used anywhere a
/// JET_INSTANCE is required.
/// </summary>
/// <param name="instance">The instance to convert.</param>
/// <returns>The JET_INSTANCE wrapped by the instance.</returns>
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
public static implicit operator JET_INSTANCE(Instance instance)
{
return instance.JetInstance;
}
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="Instance"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="Instance"/>.
/// </returns>
public override string ToString()
{
return string.Format(CultureInfo.InvariantCulture, "{0} ({1})", this.displayName, this.name);
}
/// <summary>
/// Initialize the JET_INSTANCE.
/// </summary>
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
public void Init()
{
this.Init(InitGrbit.None);
}
/// <summary>
/// Initialize the JET_INSTANCE.
/// </summary>
/// <param name="grbit">
/// Initialization options.
/// </param>
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
public void Init(InitGrbit grbit)
{
this.CheckObjectIsNotDisposed();
JET_INSTANCE instance = this.JetInstance;
// Use a constrained region so that the handle is
// always set after JetInit2 is called.
RuntimeHelpers.PrepareConstrainedRegions();
try
{
// Remember that a failure in JetInit can zero the handle
// and that JetTerm should not be called in that case.
Api.JetInit2(ref instance, grbit);
}
finally
{
this.SetHandle(instance.Value);
}
}
/// <summary>
/// Initialize the JET_INSTANCE. This API requires at least the
/// Vista version of ESENT.
/// </summary>
/// <param name="recoveryOptions">
/// Additional recovery parameters for remapping databases during
/// recovery, position where to stop recovery at, or recovery status.
/// </param>
/// <param name="grbit">
/// Initialization options.
/// </param>
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
public void Init(JET_RSTINFO recoveryOptions, InitGrbit grbit)
{
this.CheckObjectIsNotDisposed();
JET_INSTANCE instance = this.JetInstance;
// Use a constrained region so that the handle is
// always set after JetInit3 is called.
RuntimeHelpers.PrepareConstrainedRegions();
try
{
// Remember that a failure in JetInit can zero the handle
// and that JetTerm should not be called in that case.
VistaApi.JetInit3(ref instance, recoveryOptions, grbit);
}
finally
{
this.SetHandle(instance.Value);
}
}
/// <summary>
/// Terminate the JET_INSTANCE.
/// </summary>
[SuppressMessage(
"Microsoft.StyleCop.CSharp.MaintainabilityRules",
"SA1409:RemoveUnnecessaryCode",
Justification = "CER code belongs in the finally block, so the try clause is empty")]
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
public void Term()
{
// Use a constrained region so that the handle is
// always set as invalid after JetTerm is called.
RuntimeHelpers.PrepareConstrainedRegions();
try
{
// This try block deliberately left blank.
}
finally
{
// This is the code that we want in a constrained execution region.
// We need to avoid the situation where JetTerm is called
// but the handle isn't invalidated, so the instance is terminated again.
// This would happen, for example, if there was a ThreadAbortException
// between the call to JetTerm and the call to SetHandle.
//
// If an Esent exception is generated we do not want to invalidate the handle
// because the instance isn't necessarily terminated. On the other hand if a
// different exception (out of memory or thread abort) is generated we still need
// to invalidate the handle.
try
{
Api.JetTerm2(this.JetInstance, this.termGrbit);
}
catch (EsentDirtyShutdownException)
{
this.SetHandleAsInvalid();
throw;
}
this.SetHandleAsInvalid();
}
}
/// <summary>
/// Release the handle for this instance.
/// </summary>
/// <returns>True if the handle could be released.</returns>
protected override bool ReleaseHandle()
{
// The object is already marked as invalid so don't check
var instance = this.CreateInstanceFromHandle();
return (int)JET_err.Success == Api.Impl.JetTerm2(instance, this.termGrbit);
}
/// <summary>
/// Create a JET_INSTANCE from the internal handle value.
/// </summary>
/// <returns>A JET_INSTANCE containing the internal handle.</returns>
private JET_INSTANCE CreateInstanceFromHandle()
{
return new JET_INSTANCE { Value = this.handle };
}
/// <summary>
/// Check to see if this instance is invalid or closed.
/// </summary>
[SecurityPermissionAttribute(SecurityAction.LinkDemand)]
private void CheckObjectIsNotDisposed()
{
if (this.IsInvalid || this.IsClosed)
{
throw new ObjectDisposedException("Instance");
}
}
}
}

View File

@ -1,762 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="InstanceParameters.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Globalization;
using System.IO;
using Microsoft.Isam.Esent.Interop.Server2003;
using Microsoft.Isam.Esent.Interop.Vista;
using Microsoft.Isam.Esent.Interop.Windows7;
/// <summary>
/// This class provides properties to set and get system parameters
/// on an ESENT instance.
/// </summary>
public partial class InstanceParameters
{
/// <summary>
/// The instance to set parameters on.
/// </summary>
private readonly JET_INSTANCE instance;
/// <summary>
/// The session to set parameters with.
/// </summary>
private readonly JET_SESID sesid;
/// <summary>
/// Initializes a new instance of the InstanceParameters class.
/// </summary>
/// <param name="instance">
/// The instance to set parameters on. If this is JET_INSTANCE.Nil,
/// then the settings affect the default settings of future instances.
/// </param>
public InstanceParameters(JET_INSTANCE instance)
{
this.instance = instance;
this.sesid = JET_SESID.Nil;
}
/// <summary>
/// Gets or sets the relative or absolute file system path of the
/// folder that will contain the checkpoint file for the instance.
/// </summary>
public string SystemDirectory
{
get
{
return Util.AddTrailingDirectorySeparator(this.GetStringParameter(JET_param.SystemPath));
}
set
{
this.SetStringParameter(JET_param.SystemPath, Util.AddTrailingDirectorySeparator(value));
}
}
/// <summary>
/// Gets or sets the relative or absolute file system path of
/// the folder that will contain the temporary database for the instance.
/// </summary>
public string TempDirectory
{
get
{
// Older versions of Esent (e.g. Windows XP) will return the
// full path of the temporary database. Extract the directory name.
string path = this.GetStringParameter(JET_param.TempPath);
string dir = Path.GetDirectoryName(path);
return Util.AddTrailingDirectorySeparator(dir);
}
set
{
this.SetStringParameter(JET_param.TempPath, Util.AddTrailingDirectorySeparator(value));
}
}
/// <summary>
/// Gets or sets the relative or absolute file system path of the
/// folder that will contain the transaction logs for the instance.
/// </summary>
public string LogFileDirectory
{
get
{
return Util.AddTrailingDirectorySeparator(this.GetStringParameter(JET_param.LogFilePath));
}
set
{
this.SetStringParameter(JET_param.LogFilePath, Util.AddTrailingDirectorySeparator(value));
}
}
/// <summary>
/// Gets or sets the relative or absolute file system path of the
/// a folder where crash recovery or a restore operation can find
/// the databases referenced in the transaction log in the
/// specified folder.
/// </summary>
/// <remarks>
/// This parameter is ignored on Windows XP.
/// </remarks>
public string AlternateDatabaseRecoveryDirectory
{
get
{
if (EsentVersion.SupportsServer2003Features)
{
return
Util.AddTrailingDirectorySeparator(
this.GetStringParameter(Server2003Param.AlternateDatabaseRecoveryPath));
}
return null;
}
set
{
if (EsentVersion.SupportsServer2003Features)
{
this.SetStringParameter(
Server2003Param.AlternateDatabaseRecoveryPath, Util.AddTrailingDirectorySeparator(value));
}
}
}
/// <summary>
/// Gets or sets the three letter prefix used for many of the files used by
/// the database engine. For example, the checkpoint file is called EDB.CHK by
/// default because EDB is the default base name.
/// </summary>
public string BaseName
{
get
{
return this.GetStringParameter(JET_param.BaseName);
}
set
{
this.SetStringParameter(JET_param.BaseName, value);
}
}
/// <summary>
/// Gets or sets an application specific string that will be added to
/// any event log messages that are emitted by the database engine. This allows
/// easy correlation of event log messages with the source application. By default
/// the host application executable name will be used.
/// </summary>
public string EventSource
{
get
{
return this.GetStringParameter(JET_param.EventSource);
}
set
{
this.SetStringParameter(JET_param.EventSource, value);
}
}
/// <summary>
/// Gets or sets the number of sessions resources reserved for this instance.
/// A session resource directly corresponds to a JET_SESID.
/// </summary>
public int MaxSessions
{
get
{
return this.GetIntegerParameter(JET_param.MaxSessions);
}
set
{
this.SetIntegerParameter(JET_param.MaxSessions, value);
}
}
/// <summary>
/// Gets or sets the number of B+ Tree resources reserved for this instance.
/// </summary>
public int MaxOpenTables
{
get
{
return this.GetIntegerParameter(JET_param.MaxOpenTables);
}
set
{
this.SetIntegerParameter(JET_param.MaxOpenTables, value);
}
}
/// <summary>
/// Gets or sets the number of cursor resources reserved for this instance.
/// A cursor resource directly corresponds to a JET_TABLEID.
/// </summary>
public int MaxCursors
{
get
{
return this.GetIntegerParameter(JET_param.MaxCursors);
}
set
{
this.SetIntegerParameter(JET_param.MaxCursors, value);
}
}
/// <summary>
/// Gets or sets the maximum number of version store pages reserved
/// for this instance.
/// </summary>
public int MaxVerPages
{
get
{
return this.GetIntegerParameter(JET_param.MaxVerPages);
}
set
{
this.SetIntegerParameter(JET_param.MaxVerPages, value);
}
}
/// <summary>
/// Gets or sets the preferred number of version store pages reserved
/// for this instance. If the size of the version store exceeds this
/// threshold then any information that is only used for optional
/// background tasks, such as reclaiming deleted space in the database,
/// is instead sacrificed to preserve room for transactional information.
/// </summary>
public int PreferredVerPages
{
get
{
return this.GetIntegerParameter(JET_param.PreferredVerPages);
}
set
{
this.SetIntegerParameter(JET_param.PreferredVerPages, value);
}
}
/// <summary>
/// Gets or sets the the number of background cleanup work items that
/// can be queued to the database engine thread pool at any one time.
/// </summary>
public int VersionStoreTaskQueueMax
{
get
{
return this.GetIntegerParameter(JET_param.VersionStoreTaskQueueMax);
}
set
{
this.SetIntegerParameter(JET_param.VersionStoreTaskQueueMax, value);
}
}
/// <summary>
/// Gets or sets the number of temporary table resources for use
/// by an instance. This setting will affect how many temporary tables can be used at
/// the same time. If this system parameter is set to zero then no temporary database
/// will be created and any activity that requires use of the temporary database will
/// fail. This setting can be useful to avoid the I/O required to create the temporary
/// database if it is known that it will not be used.
/// </summary>
/// <remarks>
/// The use of a temporary table also requires a cursor resource.
/// </remarks>
public int MaxTemporaryTables
{
get
{
return this.GetIntegerParameter(JET_param.MaxTemporaryTables);
}
set
{
this.SetIntegerParameter(JET_param.MaxTemporaryTables, value);
}
}
/// <summary>
/// Gets or sets the size of the transaction log files. This parameter
/// should be set in units of 1024 bytes (e.g. a setting of 2048 will
/// give 2MB logfiles).
/// </summary>
public int LogFileSize
{
get
{
return this.GetIntegerParameter(JET_param.LogFileSize);
}
set
{
this.SetIntegerParameter(JET_param.LogFileSize, value);
}
}
/// <summary>
/// Gets or sets the amount of memory used to cache log records
/// before they are written to the transaction log file. The unit for this
/// parameter is the sector size of the volume that holds the transaction log files.
/// The sector size is almost always 512 bytes, so it is safe to assume that size
/// for the unit. This parameter has an impact on performance. When the database
/// engine is under heavy update load, this buffer can become full very rapidly.
/// A larger cache size for the transaction log file is critical for good update
/// performance under such a high load condition. The default is known to be too small
/// for this case.
/// Do not set this parameter to a number of buffers that is larger (in bytes) than
/// half the size of a transaction log file.
/// </summary>
public int LogBuffers
{
get
{
return this.GetIntegerParameter(JET_param.LogBuffers);
}
set
{
this.SetIntegerParameter(JET_param.LogBuffers, value);
}
}
/// <summary>
/// Gets or sets a value indicating whether circular logging is on.
/// When circular logging is off, all transaction log files that are generated
/// are retained on disk until they are no longer needed because a full backup of the
/// database has been performed. When circular logging is on, only transaction log files
/// that are younger than the current checkpoint are retained on disk. The benefit of
/// this mode is that backups are not required to retire old transaction log files.
/// </summary>
public bool CircularLog
{
get
{
return this.GetBoolParameter(JET_param.CircularLog);
}
set
{
this.SetBoolParameter(JET_param.CircularLog, value);
}
}
/// <summary>
/// Gets or sets a value indicating whether JetInit fails when the database
/// engine is configured to start using transaction log files on disk
/// that are of a different size than what is configured. Normally,
/// <see cref="Api.JetInit"/> will successfully recover the databases
/// but will fail with <see cref="JET_err.LogFileSizeMismatchDatabasesConsistent"/>
/// to indicate that the log file size is misconfigured. However, when
/// this parameter is set to true then the database engine will silently
/// delete all the old log files, start a new set of transaction log files
/// using the configured log file size. This parameter is useful when the
/// application wishes to transparently change its transaction log file
/// size yet still work transparently in upgrade and restore scenarios.
/// </summary>
public bool CleanupMismatchedLogFiles
{
get
{
return this.GetBoolParameter(JET_param.CleanupMismatchedLogFiles);
}
set
{
this.SetBoolParameter(JET_param.CleanupMismatchedLogFiles, value);
}
}
/// <summary>
/// Gets or sets the initial size of the temporary database. The size is in
/// database pages. A size of zero indicates that the default size of an ordinary
/// database should be used. It is often desirable for small applications to configure
/// the temporary database to be as small as possible. Setting this parameter to
/// <see cref="SystemParameters.PageTempDBSmallest"/> will achieve the smallest
/// temporary database possible.
/// </summary>
public int PageTempDBMin
{
get
{
return this.GetIntegerParameter(JET_param.PageTempDBMin);
}
set
{
this.SetIntegerParameter(JET_param.PageTempDBMin, value);
}
}
/// <summary>
/// Gets or sets the threshold in bytes for about how many transaction log
/// files will need to be replayed after a crash. If circular logging is enabled using
/// CircularLog then this parameter will also control the approximate amount
/// of transaction log files that will be retained on disk.
/// </summary>
public int CheckpointDepthMax
{
get
{
return this.GetIntegerParameter(JET_param.CheckpointDepthMax);
}
set
{
this.SetIntegerParameter(JET_param.CheckpointDepthMax, value);
}
}
/// <summary>
/// Gets or sets the number of pages that are added to a database file each
/// time it needs to grow to accommodate more data.
/// </summary>
public int DbExtensionSize
{
get
{
return this.GetIntegerParameter(JET_param.DbExtensionSize);
}
set
{
this.SetIntegerParameter(JET_param.DbExtensionSize, value);
}
}
/// <summary>
/// Gets or sets a value indicating whether crash recovery is on.
/// </summary>
public bool Recovery
{
get
{
return 0 == string.Compare(this.GetStringParameter(JET_param.Recovery), "on", StringComparison.OrdinalIgnoreCase);
}
set
{
if (value)
{
this.SetStringParameter(JET_param.Recovery, "on");
}
else
{
this.SetStringParameter(JET_param.Recovery, "off");
}
}
}
/// <summary>
/// Gets or sets a value indicating whether online defragmentation is enabled.
/// </summary>
public bool EnableOnlineDefrag
{
get
{
return this.GetBoolParameter(JET_param.EnableOnlineDefrag);
}
set
{
this.SetBoolParameter(JET_param.EnableOnlineDefrag, value);
}
}
/// <summary>
/// Gets or sets a value indicating whether <see cref="Api.JetAttachDatabase"/> will check for
/// indexes that were build using an older version of the NLS library in the
/// operating system.
/// </summary>
public bool EnableIndexChecking
{
get
{
return this.GetBoolParameter(JET_param.EnableIndexChecking);
}
set
{
this.SetBoolParameter(JET_param.EnableIndexChecking, value);
}
}
/// <summary>
/// Gets or sets the name of the event log the database engine uses for its event log
/// messages. By default, all event log messages will go to the Application event log. If the registry
/// key name for another event log is configured then the event log messages will go there instead.
/// </summary>
public string EventSourceKey
{
get
{
return this.GetStringParameter(JET_param.EventSourceKey);
}
set
{
this.SetStringParameter(JET_param.EventSourceKey, value);
}
}
/// <summary>
/// Gets or sets a value indicating whether informational event
/// log messages that would ordinarily be generated by the
/// database engine will be suppressed.
/// </summary>
public bool NoInformationEvent
{
get
{
return this.GetBoolParameter(JET_param.NoInformationEvent);
}
set
{
this.SetBoolParameter(JET_param.NoInformationEvent, value);
}
}
/// <summary>
/// Gets or sets the detail level of eventlog messages that are emitted
/// to the eventlog by the database engine. Higher numbers will result
/// in more detailed eventlog messages.
/// </summary>
public EventLoggingLevels EventLoggingLevel
{
get
{
return (EventLoggingLevels)this.GetIntegerParameter(JET_param.EventLoggingLevel);
}
set
{
this.SetIntegerParameter(JET_param.EventLoggingLevel, (int)value);
}
}
/// <summary>
/// Gets or sets a value indicating whether only one database is allowed to
/// be opened using JetOpenDatabase by a given session at one time.
/// The temporary database is excluded from this restriction.
/// </summary>
public bool OneDatabasePerSession
{
get
{
return this.GetBoolParameter(JET_param.OneDatabasePerSession);
}
set
{
this.SetBoolParameter(JET_param.OneDatabasePerSession, value);
}
}
/// <summary>
/// Gets or sets a value indicating whether ESENT will silently create folders
/// that are missing in its filesystem paths.
/// </summary>
public bool CreatePathIfNotExist
{
get
{
return this.GetBoolParameter(JET_param.CreatePathIfNotExist);
}
set
{
this.SetBoolParameter(JET_param.CreatePathIfNotExist, value);
}
}
/// <summary>
/// Gets or sets a value giving the number of B+ Tree resources cached by
/// the instance after the tables they represent have been closed by
/// the application. Large values for this parameter will cause the
/// database engine to use more memory but will increase the speed
/// with which a large number of tables can be opened randomly by
/// the application. This is useful for applications that have a
/// schema with a very large number of tables.
/// <para>
/// Supported on Windows Vista and up. Ignored on Windows XP and
/// Windows Server 2003.
/// </para>
/// </summary>
public int CachedClosedTables
{
get
{
if (EsentVersion.SupportsVistaFeatures)
{
return this.GetIntegerParameter(VistaParam.CachedClosedTables);
}
return 0;
}
set
{
if (EsentVersion.SupportsVistaFeatures)
{
this.SetIntegerParameter(VistaParam.CachedClosedTables, value);
}
}
}
/// <summary>
/// Gets or sets a the number of logs that esent will defer database
/// flushes for. This can be used to increase database recoverability if
/// failures cause logfiles to be lost.
/// <para>
/// Supported on Windows 7 and up. Ignored on Windows XP,
/// Windows Server 2003, Windows Vista and Windows Server 2008.
/// </para>
/// </summary>
public int WaypointLatency
{
get
{
if (EsentVersion.SupportsWindows7Features)
{
return this.GetIntegerParameter(Windows7Param.WaypointLatency);
}
// older versions have no waypoint
return 0;
}
set
{
if (EsentVersion.SupportsWindows7Features)
{
this.SetIntegerParameter(Windows7Param.WaypointLatency, value);
}
}
}
/// <summary>
/// Gets or sets a value indicating whether <see cref="Api.JetAttachDatabase"/> will
/// delete indexes that were build using an older version of the NLS library in the
/// operating system.
/// </summary>
public bool EnableIndexCleanup
{
get
{
return this.GetBoolParameter(JET_param.EnableIndexCleanup);
}
set
{
this.SetBoolParameter(JET_param.EnableIndexCleanup, value);
}
}
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="InstanceParameters"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="InstanceParameters"/>.
/// </returns>
public override string ToString()
{
return string.Format(CultureInfo.InvariantCulture, "InstanceParameters (0x{0:x})", this.instance.Value);
}
/// <summary>
/// Set a system parameter which is a string.
/// </summary>
/// <param name="param">The parameter to set.</param>
/// <param name="value">The value to set.</param>
private void SetStringParameter(JET_param param, string value)
{
Api.JetSetSystemParameter(this.instance, this.sesid, param, 0, value);
}
/// <summary>
/// Get a system parameter which is a string.
/// </summary>
/// <param name="param">The parameter to get.</param>
/// <returns>The value of the parameter.</returns>
private string GetStringParameter(JET_param param)
{
int ignored = 0;
string value;
Api.JetGetSystemParameter(this.instance, this.sesid, param, ref ignored, out value, 1024);
return value;
}
/// <summary>
/// Set a system parameter which is an integer.
/// </summary>
/// <param name="param">The parameter to set.</param>
/// <param name="value">The value to set.</param>
private void SetIntegerParameter(JET_param param, int value)
{
Api.JetSetSystemParameter(this.instance, this.sesid, param, value, null);
}
/// <summary>
/// Get a system parameter which is an integer.
/// </summary>
/// <param name="param">The parameter to get.</param>
/// <returns>The value of the parameter.</returns>
private int GetIntegerParameter(JET_param param)
{
int value = 0;
string ignored;
Api.JetGetSystemParameter(this.instance, this.sesid, param, ref value, out ignored, 0);
return value;
}
/// <summary>
/// Set a system parameter which is a boolean.
/// </summary>
/// <param name="param">The parameter to set.</param>
/// <param name="value">The value to set.</param>
private void SetBoolParameter(JET_param param, bool value)
{
if (value)
{
Api.JetSetSystemParameter(this.instance, this.sesid, param, 1, null);
}
else
{
Api.JetSetSystemParameter(this.instance, this.sesid, param, 0, null);
}
}
/// <summary>
/// Get a system parameter which is a boolean.
/// </summary>
/// <param name="param">The parameter to get.</param>
/// <returns>The value of the parameter.</returns>
private bool GetBoolParameter(JET_param param)
{
int value = 0;
string ignored;
Api.JetGetSystemParameter(this.instance, this.sesid, param, ref value, out ignored, 0);
return value != 0;
}
}
}

View File

@ -1,69 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="Int16ColumnValue.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
/// <summary>
/// An <see cref="short"/> column value.
/// </summary>
public class Int16ColumnValue : ColumnValueOfStruct<short>
{
/// <summary>
/// Gets the size of the value in the column. This returns 0 for
/// variable sized columns (i.e. binary and string).
/// </summary>
protected override int Size
{
[DebuggerStepThrough]
get { return sizeof(short); }
}
/// <summary>
/// Recursive SetColumns method for data pinning. This populates the buffer and
/// calls the inherited SetColumns method.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to set the columns in. An update should be prepared.
/// </param>
/// <param name="columnValues">
/// Column values to set.
/// </param>
/// <param name="nativeColumns">
/// Structures to put the pinned data in.
/// </param>
/// <param name="i">Offset of this object in the array.</param>
/// <returns>An error code.</returns>
internal override unsafe int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i)
{
var data = this.Value.GetValueOrDefault();
return this.SetColumns(sesid, tableid, columnValues, nativeColumns, i, &data, sizeof(short), this.Value.HasValue);
}
/// <summary>
/// Given data retrieved from ESENT, decode the data and set the value in the ColumnValue object.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within the bytes.</param>
/// <param name="count">The number of bytes to decode.</param>
/// <param name="err">The error returned from ESENT.</param>
protected override void GetValueFromBytes(byte[] value, int startIndex, int count, int err)
{
if (JET_wrn.ColumnNull == (JET_wrn)err)
{
this.Value = null;
}
else
{
this.CheckDataCount(count);
this.Value = BitConverter.ToInt16(value, startIndex);
}
}
}
}

View File

@ -1,69 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="Int32ColumnValue.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
/// <summary>
/// An <see cref="int"/> column value.
/// </summary>
public class Int32ColumnValue : ColumnValueOfStruct<int>
{
/// <summary>
/// Gets the size of the value in the column. This returns 0 for
/// variable sized columns (i.e. binary and string).
/// </summary>
protected override int Size
{
[DebuggerStepThrough]
get { return sizeof(int); }
}
/// <summary>
/// Recursive SetColumns method for data pinning. This populates the buffer and
/// calls the inherited SetColumns method.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to set the columns in. An update should be prepared.
/// </param>
/// <param name="columnValues">
/// Column values to set.
/// </param>
/// <param name="nativeColumns">
/// Structures to put the pinned data in.
/// </param>
/// <param name="i">Offset of this object in the array.</param>
/// <returns>An error code.</returns>
internal override unsafe int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i)
{
var data = this.Value.GetValueOrDefault();
return this.SetColumns(sesid, tableid, columnValues, nativeColumns, i, &data, sizeof(int), this.Value.HasValue);
}
/// <summary>
/// Given data retrieved from ESENT, decode the data and set the value in the ColumnValue object.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within the bytes.</param>
/// <param name="count">The number of bytes to decode.</param>
/// <param name="err">The error returned from ESENT.</param>
protected override void GetValueFromBytes(byte[] value, int startIndex, int count, int err)
{
if (JET_wrn.ColumnNull == (JET_wrn)err)
{
this.Value = null;
}
else
{
this.CheckDataCount(count);
this.Value = BitConverter.ToInt32(value, startIndex);
}
}
}
}

View File

@ -1,69 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="Int64ColumnValue.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
/// <summary>
/// An <see cref="long"/> column value.
/// </summary>
public class Int64ColumnValue : ColumnValueOfStruct<long>
{
/// <summary>
/// Gets the size of the value in the column. This returns 0 for
/// variable sized columns (i.e. binary and string).
/// </summary>
protected override int Size
{
[DebuggerStepThrough]
get { return sizeof(long); }
}
/// <summary>
/// Recursive SetColumns method for data pinning. This populates the buffer and
/// calls the inherited SetColumns method.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">
/// The table to set the columns in. An update should be prepared.
/// </param>
/// <param name="columnValues">
/// Column values to set.
/// </param>
/// <param name="nativeColumns">
/// Structures to put the pinned data in.
/// </param>
/// <param name="i">Offset of this object in the array.</param>
/// <returns>An error code.</returns>
internal override unsafe int SetColumns(JET_SESID sesid, JET_TABLEID tableid, ColumnValue[] columnValues, NATIVE_SETCOLUMN* nativeColumns, int i)
{
var data = this.Value.GetValueOrDefault();
return this.SetColumns(sesid, tableid, columnValues, nativeColumns, i, &data, sizeof(long), this.Value.HasValue);
}
/// <summary>
/// Given data retrieved from ESENT, decode the data and set the value in the ColumnValue object.
/// </summary>
/// <param name="value">An array of bytes.</param>
/// <param name="startIndex">The starting position within the bytes.</param>
/// <param name="count">The number of bytes to decode.</param>
/// <param name="err">The error returned from ESENT.</param>
protected override void GetValueFromBytes(byte[] value, int startIndex, int count, int err)
{
if (JET_wrn.ColumnNull == (JET_wrn)err)
{
this.Value = null;
}
else
{
this.CheckDataCount(count);
this.Value = BitConverter.ToInt64(value, startIndex);
}
}
}
}

View File

@ -1,192 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="InternalApi.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
/// <summary>
/// Internal-only methods of the Api.
/// </summary>
public static partial class Api
{
/// <summary>
/// The JetSetColumn function modifies a single column value in a modified record to be inserted or to
/// update the current record. It can overwrite an existing value, add a new value to a sequence of
/// values in a multi-valued column, remove a value from a sequence of values in a multi-valued column,
/// or update all or part of a long value (a column of type <see cref="JET_coltyp.LongText"/>
/// or <see cref="JET_coltyp.LongBinary"/>).
/// </summary>
/// <remarks>
/// This is an internal-only version of the API that takes a data buffer and an offset into the buffer.
/// </remarks>
/// <param name="sesid">The session which is performing the update.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
/// <param name="dataSize">The size of data to set.</param>
/// <param name="dataOffset">The offset in the data buffer to set data from.</param>
/// <param name="grbit">SetColumn options.</param>
/// <param name="setinfo">Used to specify itag or long-value offset.</param>
/// <returns>A warning value.</returns>
public static JET_wrn JetSetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, byte[] data, int dataSize, int dataOffset, SetColumnGrbit grbit, JET_SETINFO setinfo)
{
if (dataOffset < 0
|| (null != data && 0 != dataSize && dataOffset >= data.Length)
|| (null == data && dataOffset != 0))
{
throw new ArgumentOutOfRangeException(
"dataOffset",
dataOffset,
"must be inside the data buffer");
}
if (null != data && dataSize > checked(data.Length - dataOffset) && (SetColumnGrbit.SizeLV != (grbit & SetColumnGrbit.SizeLV)))
{
throw new ArgumentOutOfRangeException(
"dataSize",
dataSize,
"cannot be greater than the length of the data (unless the SizeLV option is used)");
}
unsafe
{
fixed (byte* pointer = data)
{
return Api.JetSetColumn(sesid, tableid, columnid, new IntPtr(pointer + dataOffset), dataSize, grbit, setinfo);
}
}
}
/// <summary>
/// Retrieves a single column value from the current record. The record is that
/// record associated with the index entry at the current position of the cursor.
/// Alternatively, this function can retrieve a column from a record being created
/// in the cursor copy buffer. This function can also retrieve column data from an
/// index entry that references the current record. In addition to retrieving the
/// actual column value, JetRetrieveColumn can also be used to retrieve the size
/// of a column, before retrieving the column data itself so that application
/// buffers can be sized appropriately.
/// </summary>
/// <remarks>
/// This is an internal method that takes a buffer offset as well as size.
/// </remarks>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to retrieve the column from.</param>
/// <param name="columnid">The columnid to retrieve.</param>
/// <param name="data">The data buffer to be retrieved into.</param>
/// <param name="dataSize">The size of the data buffer.</param>
/// <param name="dataOffset">Offset into the data buffer to read data into.</param>
/// <param name="actualDataSize">Returns the actual size of the data buffer.</param>
/// <param name="grbit">Retrieve column options.</param>
/// <param name="retinfo">
/// If pretinfo is give as NULL then the function behaves as though an itagSequence
/// of 1 and an ibLongValue of 0 (zero) were given. This causes column retrieval to
/// retrieve the first value of a multi-valued column, and to retrieve long data at
/// offset 0 (zero).
/// </param>
/// <returns>An ESENT warning code.</returns>
public static JET_wrn JetRetrieveColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, byte[] data, int dataSize, int dataOffset, out int actualDataSize, RetrieveColumnGrbit grbit, JET_RETINFO retinfo)
{
if (dataOffset < 0
|| (null != data && 0 != dataSize && dataOffset >= data.Length)
|| (null == data && dataOffset != 0))
{
throw new ArgumentOutOfRangeException(
"dataOffset",
dataOffset,
"must be inside the data buffer");
}
if ((null == data && dataSize > 0) || (null != data && dataSize > data.Length))
{
throw new ArgumentOutOfRangeException(
"dataSize",
dataSize,
"cannot be greater than the length of the data");
}
unsafe
{
fixed (byte* pointer = data)
{
return Api.JetRetrieveColumn(
sesid, tableid, columnid, new IntPtr(pointer + dataOffset), dataSize, out actualDataSize, grbit, retinfo);
}
}
}
/// <summary>
/// Retrieves a single column value from the current record. The record is that
/// record associated with the index entry at the current position of the cursor.
/// Alternatively, this function can retrieve a column from a record being created
/// in the cursor copy buffer. This function can also retrieve column data from an
/// index entry that references the current record. In addition to retrieving the
/// actual column value, JetRetrieveColumn can also be used to retrieve the size
/// of a column, before retrieving the column data itself so that application
/// buffers can be sized appropriately.
/// </summary>
/// <remarks>
/// This is an internal-use version that takes an IntPtr.
/// </remarks>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to retrieve the column from.</param>
/// <param name="columnid">The columnid to retrieve.</param>
/// <param name="data">The data buffer to be retrieved into.</param>
/// <param name="dataSize">The size of the data buffer.</param>
/// <param name="actualDataSize">Returns the actual size of the data buffer.</param>
/// <param name="grbit">Retrieve column options.</param>
/// <param name="retinfo">
/// If pretinfo is give as NULL then the function behaves as though an itagSequence
/// of 1 and an ibLongValue of 0 (zero) were given. This causes column retrieval to
/// retrieve the first value of a multi-valued column, and to retrieve long data at
/// offset 0 (zero).
/// </param>
/// <returns>An ESENT warning code.</returns>
internal static JET_wrn JetRetrieveColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, IntPtr data, int dataSize, out int actualDataSize, RetrieveColumnGrbit grbit, JET_RETINFO retinfo)
{
return Api.Check(Impl.JetRetrieveColumn(sesid, tableid, columnid, data, dataSize, out actualDataSize, grbit, retinfo));
}
/// <summary>
/// Constructs search keys that may then be used by JetSeek and JetSetIndexRange.
/// </summary>
/// <remarks>
/// This is an internal (unsafe) version that takes an IntPtr.
/// </remarks>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="dataSize">Size of the data.</param>
/// <param name="grbit">Key options.</param>
internal static void JetMakeKey(JET_SESID sesid, JET_TABLEID tableid, IntPtr data, int dataSize, MakeKeyGrbit grbit)
{
Api.Check(Impl.JetMakeKey(sesid, tableid, data, dataSize, grbit));
}
/// <summary>
/// The JetSetColumn function modifies a single column value in a modified record to be inserted or to
/// update the current record. It can overwrite an existing value, add a new value to a sequence of
/// values in a multi-valued column, remove a value from a sequence of values in a multi-valued column,
/// or update all or part of a long value, a column of type JET_coltyp.LongText or JET_coltyp.LongBinary.
/// </summary>
/// <remarks>
/// This method takes an IntPtr and is intended for internal use only.
/// </remarks>
/// <param name="sesid">The session which is performing the update.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
/// <param name="dataSize">The size of data to set.</param>
/// <param name="grbit">SetColumn options.</param>
/// <param name="setinfo">Used to specify itag or long-value offset.</param>
/// <returns>A warning value.</returns>
internal static JET_wrn JetSetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, IntPtr data, int dataSize, SetColumnGrbit grbit, JET_SETINFO setinfo)
{
return Api.Check(Impl.JetSetColumn(sesid, tableid, columnid, data, dataSize, grbit, setinfo));
}
}
}

View File

@ -1,56 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="IntersectIndexesEnumerator.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
/// <summary>
/// Enumerator that can intersect indexes and return the intersected bookmarks.
/// </summary>
internal sealed class IntersectIndexesEnumerator : TableEnumerator<byte[]>
{
/// <summary>
/// The ranges to intersect.
/// </summary>
private readonly JET_INDEXRANGE[] ranges;
/// <summary>
/// The recordlist containing the result of the intersection.
/// </summary>
private JET_RECORDLIST recordlist;
/// <summary>
/// Initializes a new instance of the <see cref="IntersectIndexesEnumerator"/> class.
/// </summary>
/// <param name="sesid">
/// The session to use.
/// </param>
/// <param name="ranges">
/// The ranges to intersect.
/// </param>
public IntersectIndexesEnumerator(JET_SESID sesid, JET_INDEXRANGE[] ranges) : base(sesid)
{
this.ranges = ranges;
}
/// <summary>
/// Open the table to be enumerated. This should set <see cref="TableEnumerator{T}.TableidToEnumerate"/>.
/// </summary>
protected override void OpenTable()
{
Api.JetIntersectIndexes(this.Sesid, this.ranges, this.ranges.Length, out this.recordlist, IntersectIndexesGrbit.None);
this.TableidToEnumerate = this.recordlist.tableid;
}
/// <summary>
/// Gets the entry the cursor is currently positioned on.
/// </summary>
/// <returns>The entry the cursor is currently positioned on.</returns>
protected override byte[] GetCurrent()
{
return Api.RetrieveColumn(this.Sesid, this.TableidToEnumerate, this.recordlist.columnidBookmark);
}
}
}

View File

@ -1,44 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="JET_eventlogginglevel.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
/// <summary>
/// Options for EventLoggingLevel.
/// </summary>
public enum EventLoggingLevels
{
/// <summary>
/// Disable all events.
/// </summary>
Disable = 0,
/// <summary>
/// Default level. Windows 7 and later.
/// </summary>
Min = 1,
/// <summary>
/// Low verbosity and lower. Windows 7 and later.
/// </summary>
Low = 25,
/// <summary>
/// Medium verbosity and lower. Windows 7 and later.
/// </summary>
Medium = 50,
/// <summary>
/// High verbosity and lower. Windows 7 and later.
/// </summary>
High = 75,
/// <summary>
/// All events.
/// </summary>
Max = 100,
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,175 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="JetCallbackWrapper.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
using System.Globalization;
using System.Reflection;
using System.Runtime.CompilerServices;
/// <summary>
/// A multi-purpose callback function used by the database engine to inform
/// the application of an event involving online defragmentation and cursor
/// state notifications.
/// </summary>
/// <param name="sesid">The session for which the callback is being made.</param>
/// <param name="dbid">The database for which the callback is being made.</param>
/// <param name="tableid">The cursor for which the callback is being made.</param>
/// <param name="cbtyp">The operation for which the callback is being made.</param>
/// <param name="arg1">First callback-specific argument.</param>
/// <param name="arg2">Second callback-specific argument.</param>
/// <param name="context">Callback context.</param>
/// <param name="unused">This parameter is not used.</param>
/// <returns>An ESENT error code.</returns>
internal delegate JET_err NATIVE_CALLBACK(
IntPtr sesid,
uint dbid,
IntPtr tableid,
uint cbtyp,
IntPtr arg1,
IntPtr arg2,
IntPtr context,
IntPtr unused);
/// <summary>
/// Wraps a NATIVE_CALLBACK callback around a JET_CALLBACK. This is
/// used to catch exceptions and provide argument conversion.
/// </summary>
internal sealed class JetCallbackWrapper
{
/// <summary>
/// API call tracing.
/// </summary>
private static readonly TraceSwitch TraceSwitch = new TraceSwitch("ESENT JetCallbackWrapper", "Wrapper around unmanaged ESENT callback");
/// <summary>
/// The wrapped status callback.
/// </summary>
private readonly WeakReference wrappedCallback;
/// <summary>
/// The native version of the callback. This will actually be a closure
/// because we are calling a non-static method. Keep track of it here
/// to make sure that it isn't garbage collected.
/// </summary>
private readonly NATIVE_CALLBACK nativeCallback;
#if !MANAGEDESENT_ON_WSA
/// <summary>
/// Initializes static members of the <see cref="JetCallbackWrapper"/> class.
/// </summary>
static JetCallbackWrapper()
{
// We don't want a JIT failure when trying to execute the callback
// because that would throw an exception through ESENT, corrupting it.
// It is fine for the wrapped callback to fail because CallbackImpl
// will catch the exception and deal with it.
RuntimeHelpers.PrepareMethod(typeof(StatusCallbackWrapper).GetMethod(
"CallbackImpl",
BindingFlags.NonPublic | BindingFlags.Instance).MethodHandle);
}
#endif // !MANAGEDESENT_ON_WSA
/// <summary>
/// Initializes a new instance of the JetCallbackWrapper class.
/// </summary>
/// <param name="callback">
/// The managed callback to use.
/// </param>
public JetCallbackWrapper(JET_CALLBACK callback)
{
this.wrappedCallback = new WeakReference(callback);
this.nativeCallback = this.CallbackImpl;
Debug.Assert(this.wrappedCallback.IsAlive, "Callback isn't alive");
}
/// <summary>
/// Gets a value indicating whether the wrapped callback has been garbage
/// collected.
/// </summary>
public bool IsAlive
{
get
{
return this.wrappedCallback.IsAlive;
}
}
/// <summary>
/// Gets a NATIVE_CALLBACK callback that wraps the managed callback.
/// </summary>
public NATIVE_CALLBACK NativeCallback
{
get
{
return this.nativeCallback;
}
}
/// <summary>
/// Determine if the callback is wrapping the specified JET_CALLBACK.
/// </summary>
/// <param name="callback">The callback.</param>
/// <returns>True if this wrapper is wrapping the callback.</returns>
public bool IsWrapping(JET_CALLBACK callback)
{
return callback.Equals(this.wrappedCallback.Target);
}
/// <summary>
/// Callback function for native code. We don't want to throw an exception through
/// unmanaged ESENT because that will corrupt ESENT's internal state. Instead we
/// catch all exceptions and return an error instead. We use a CER to make catching
/// the exceptions as reliable as possible.
/// </summary>
/// <param name="nativeSesid">The session for which the callback is being made.</param>
/// <param name="nativeDbid">The database for which the callback is being made.</param>
/// <param name="nativeTableid">The cursor for which the callback is being made.</param>
/// <param name="nativeCbtyp">The operation for which the callback is being made.</param>
/// <param name="arg1">First callback-specific argument.</param>
/// <param name="arg2">Second callback-specific argument.</param>
/// <param name="nativeContext">Callback context.</param>
/// <param name="unused">This parameter is not used.</param>
/// <returns>An ESENT error code.</returns>
private JET_err CallbackImpl(
IntPtr nativeSesid,
uint nativeDbid,
IntPtr nativeTableid,
uint nativeCbtyp,
IntPtr arg1,
IntPtr arg2,
IntPtr nativeContext,
IntPtr unused)
{
RuntimeHelpers.PrepareConstrainedRegions();
try
{
var sesid = new JET_SESID { Value = nativeSesid };
var dbid = new JET_DBID { Value = nativeDbid };
var tableid = new JET_TABLEID { Value = nativeTableid };
JET_cbtyp cbtyp = (JET_cbtyp)nativeCbtyp;
Debug.Assert(this.wrappedCallback.IsAlive, "Wrapped callback has been garbage collected");
// This will throw an exception if the wrapped callback has been collected. The exception
// will be handled below.
JET_CALLBACK callback = (JET_CALLBACK)this.wrappedCallback.Target;
return callback(sesid, dbid, tableid, cbtyp, null, null, nativeContext, IntPtr.Zero);
}
catch (Exception ex)
{
// Thread aborts aren't handled here. ESENT callbacks can execute on client threads or
// internal ESENT threads so it isn't clear what should be done on an abort.
Trace.WriteLineIf(
TraceSwitch.TraceWarning,
string.Format(CultureInfo.InvariantCulture, "Caught Exception {0}", ex));
return JET_err.CallbackFailed;
}
}
}
}

View File

@ -1,67 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="JetCapabilities.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop.Implementation
{
/// <summary>
/// Describes the functionality exposed by an object which implements IJetApi.
/// </summary>
internal sealed class JetCapabilities
{
/// <summary>
/// Gets or sets a value indicating whether Windows Server 2003 features
/// (in the Interop.Server2003 namespace) are supported.
/// </summary>
public bool SupportsServer2003Features { get; set; }
/// <summary>
/// Gets or sets a value indicating whether Vista features (in the
/// Interop.Vista namespace) are supported.
/// </summary>
public bool SupportsVistaFeatures { get; set; }
/// <summary>
/// Gets or sets a value indicating whether Win7 features (in the
/// Interop.Windows7 namespace) are supported.
/// </summary>
public bool SupportsWindows7Features { get; set; }
/// <summary>
/// Gets or sets a value indicating whether Win8 features (in the
/// Interop.Windows8 namespace) are supported.
/// </summary>
public bool SupportsWindows8Features { get; set; }
/// <summary>
/// Gets or sets a value indicating whether Win8.1 features (in the
/// Interop.Windows81 namespace) are supported.
/// </summary>
public bool SupportsWindows81Features { get; set; }
/// <summary>
/// Gets or sets a value indicating whether Win10 features (in the
/// Interop.Windows10 namespace) are supported.
/// </summary>
public bool SupportsWindows10Features { get; set; }
/// <summary>
/// Gets or sets a value indicating whether unicode file paths are supported.
/// </summary>
public bool SupportsUnicodePaths { get; set; }
/// <summary>
/// Gets or sets a value indicating whether large (> 255 byte) keys are supported.
/// The key size for an index can be specified in the <see cref="JET_INDEXCREATE"/>
/// object.
/// </summary>
public bool SupportsLargeKeys { get; set; }
/// <summary>
/// Gets or sets the maximum number of components in a sort or index key.
/// </summary>
public int ColumnsKeyMost { get; set; }
}
}

View File

@ -1,191 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="jet_indexcreate3.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices;
using Microsoft.Isam.Esent.Interop.Vista;
/// <summary>
/// The native version of the JET_INDEXCREATE3 structure.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
[SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules",
"SA1305:FieldNamesMustNotUseHungarianNotation",
Justification = "This should match the unmanaged API, which isn't capitalized.")]
[SuppressMessage(
"Microsoft.StyleCop.CSharp.NamingRules",
"SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter",
Justification = "This should match the unmanaged API, which isn't capitalized.")]
internal unsafe struct NATIVE_INDEXCREATE3
{
/// <summary>
/// Size of the structure.
/// </summary>
public uint cbStruct;
/// <summary>
/// Name of the index.
/// </summary>
public IntPtr szIndexName;
/// <summary>
/// Index key description.
/// </summary>
public IntPtr szKey;
/// <summary>
/// Size of index key description.
/// </summary>
public uint cbKey;
/// <summary>
/// Index options.
/// </summary>
public uint grbit;
/// <summary>
/// Index density.
/// </summary>
public uint ulDensity;
/// <summary>
/// Pointer to unicode sort options.
/// </summary>
public NATIVE_UNICODEINDEX2* pidxUnicode;
/// <summary>
/// Maximum size of column data to index. This can also be
/// a pointer to a JET_TUPLELIMITS structure.
/// </summary>
public IntPtr cbVarSegMac;
/// <summary>
/// Pointer to array of conditional columns.
/// </summary>
public IntPtr rgconditionalcolumn;
/// <summary>
/// Count of conditional columns.
/// </summary>
public uint cConditionalColumn;
/// <summary>
/// Returned error from index creation.
/// </summary>
public int err;
/// <summary>
/// Maximum size of the key.
/// </summary>
public uint cbKeyMost;
/// <summary>
/// A <see cref="NATIVE_SPACEHINTS"/> pointer.
/// </summary>
public IntPtr pSpaceHints;
}
/// <summary>
/// Contains the information needed to create an index over data in an ESE database.
/// </summary>
public sealed partial class JET_INDEXCREATE : IContentEquatable<JET_INDEXCREATE>, IDeepCloneable<JET_INDEXCREATE>
{
/// <summary>
/// Gets the native (interop) version of this object, except for
/// <see cref="szIndexName"/> and <see cref="szKey"/>.
/// </summary>
/// <remarks>The cbKey holds the length of the key in bytes, and does not need to be adjusted.</remarks>
/// <returns>The native (interop) version of this object.</returns>
internal NATIVE_INDEXCREATE3 GetNativeIndexcreate3()
{
this.CheckMembersAreValid();
var native = new NATIVE_INDEXCREATE3();
native.cbStruct = checked((uint)Marshal.SizeOf(typeof(NATIVE_INDEXCREATE3)));
// szIndexName and szKey are converted at pinvoke time.
//
// native.szIndexName = this.szIndexName;
// native.szKey = this.szKey;
native.cbKey = checked((uint)this.cbKey * sizeof(char));
native.grbit = unchecked((uint)this.grbit);
native.ulDensity = checked((uint)this.ulDensity);
native.cbVarSegMac = new IntPtr(this.cbVarSegMac);
native.cConditionalColumn = checked((uint)this.cConditionalColumn);
if (0 != this.cbKeyMost)
{
native.cbKeyMost = checked((uint)this.cbKeyMost);
native.grbit |= unchecked((uint)VistaGrbits.IndexKeyMost);
}
return native;
}
/// <summary>
/// Sets only the output fields of the object from a <see cref="NATIVE_INDEXCREATE3"/> struct,
/// specifically <see cref="err"/>.
/// </summary>
/// <param name="value">
/// The native indexcreate to set the values from.
/// </param>
internal void SetFromNativeIndexCreate(ref NATIVE_INDEXCREATE3 value)
{
this.err = (JET_err)value.err;
}
/// <summary>
/// Sets all of the fields (not just output fields) of the object from a <see cref="NATIVE_INDEXCREATE3"/> struct,
/// specifically <see cref="err"/>.
/// </summary>
/// <param name="value">
/// The native indexcreate to set the values from.
/// </param>
internal void SetAllFromNativeIndexCreate(ref NATIVE_INDEXCREATE3 value)
{
this.szIndexName = Marshal.PtrToStringUni(value.szIndexName);
this.cbKey = unchecked((int)value.cbKey / sizeof(char));
this.szKey = Marshal.PtrToStringUni(value.szKey, this.cbKey);
if (this.cbKey != this.szKey.Length)
{
throw new ArgumentException(string.Format("cbKey {0} != szKey.Length {1}", this.cbKey, this.szKey.Length));
}
this.grbit = unchecked((CreateIndexGrbit)value.grbit);
this.ulDensity = unchecked((int)value.ulDensity);
unsafe
{
this.pidxUnicode = new JET_UNICODEINDEX(ref *value.pidxUnicode);
}
this.cbVarSegMac = (int)value.cbVarSegMac;
this.cConditionalColumn = unchecked((int)value.cConditionalColumn);
this.rgconditionalcolumn = new JET_CONDITIONALCOLUMN[this.cConditionalColumn];
int sizeofConditionalColumn = Marshal.SizeOf(typeof(NATIVE_CONDITIONALCOLUMN));
for (int i = 0; i < this.cConditionalColumn; ++i)
{
IntPtr addressOfElement = value.rgconditionalcolumn + i * sizeofConditionalColumn;
NATIVE_CONDITIONALCOLUMN nativeConditionalColumn =
(NATIVE_CONDITIONALCOLUMN)Marshal.PtrToStructure(addressOfElement, typeof(NATIVE_CONDITIONALCOLUMN));
this.rgconditionalcolumn[i] = new JET_CONDITIONALCOLUMN(ref nativeConditionalColumn);
}
this.err = (JET_err)value.err;
this.cbKeyMost = unchecked((int)value.cbKeyMost);
var nativeSpaceHints = (NATIVE_SPACEHINTS)Marshal.PtrToStructure(value.pSpaceHints, typeof(NATIVE_SPACEHINTS));
this.pSpaceHints = new JET_SPACEHINTS();
this.pSpaceHints.SetFromNativeSpaceHints(nativeSpaceHints);
}
}
}

View File

@ -1,97 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="jet_opentemporarytable2.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop.Vista
{
using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.InteropServices;
/// <summary>
/// The native version of the JET_OPENTEMPORARYTABLE2 structure.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
[SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules",
"SA1305:FieldNamesMustNotUseHungarianNotation",
Justification = "This should match the unmanaged API, which isn't capitalized.")]
[SuppressMessage(
"Microsoft.StyleCop.CSharp.NamingRules",
"SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter",
Justification = "This should match the unmanaged API, which isn't capitalized.")]
internal unsafe struct NATIVE_OPENTEMPORARYTABLE2
{
/// <summary>
/// Size of the structure.
/// </summary>
public uint cbStruct;
/// <summary>
/// Columns to create.
/// </summary>
public NATIVE_COLUMNDEF* prgcolumndef;
/// <summary>
/// Number of entries in prgcolumndef.
/// </summary>
public uint ccolumn;
/// <summary>
/// Optional pointer to unicode index information.
/// </summary>
public NATIVE_UNICODEINDEX2* pidxunicode;
/// <summary>
/// Table options.
/// </summary>
public uint grbit;
/// <summary>
/// Pointer to array of returned columnids. This
/// should have at least ccolumn entries.
/// </summary>
public uint* rgcolumnid;
/// <summary>
/// Maximum key size.
/// </summary>
public uint cbKeyMost;
/// <summary>
/// Maximum amount of data used to construct a key.
/// </summary>
public uint cbVarSegMac;
/// <summary>
/// Returns the tableid of the new table.
/// </summary>
public IntPtr tableid;
}
/// <summary>
/// A collection of parameters for the JetOpenTemporaryTable method.
/// </summary>
public partial class JET_OPENTEMPORARYTABLE
{
/// <summary>
/// Returns the unmanaged opentemporarytable that represents this managed class.
/// </summary>
/// <returns>
/// A native (interop) version of the JET_OPENTEMPORARYTABLE.
/// </returns>
internal NATIVE_OPENTEMPORARYTABLE2 GetNativeOpenTemporaryTable2()
{
this.CheckDataSize();
var openTemporaryTable = new NATIVE_OPENTEMPORARYTABLE2();
openTemporaryTable.cbStruct = checked((uint)Marshal.SizeOf(typeof(NATIVE_OPENTEMPORARYTABLE2)));
openTemporaryTable.ccolumn = checked((uint)this.ccolumn);
openTemporaryTable.grbit = (uint)this.grbit;
openTemporaryTable.cbKeyMost = checked((uint)this.cbKeyMost);
openTemporaryTable.cbVarSegMac = checked((uint)this.cbVarSegMac);
return openTemporaryTable;
}
}
}

View File

@ -1,159 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="jet_tablecreate4.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Runtime.InteropServices;
using Microsoft.Isam.Esent.Interop.Implementation;
/// <summary>
/// The native version of the <see cref="JET_TABLECREATE"/> structure. This includes callbacks,
/// space hints, and uses NATIVE_INDEXCREATE4.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
[SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules",
"SA1305:FieldNamesMustNotUseHungarianNotation",
Justification = "This should match the unmanaged API, which isn't capitalized.")]
[SuppressMessage(
"Microsoft.StyleCop.CSharp.NamingRules",
"SA1307:AccessibleFieldsMustBeginWithUpperCaseLetter",
Justification = "This should match the unmanaged API, which isn't capitalized.")]
internal unsafe struct NATIVE_TABLECREATE4
{
/// <summary>
/// Size of the structure.
/// </summary>
public uint cbStruct;
/// <summary>
/// Name of the table to create.
/// </summary>
[MarshalAs(UnmanagedType.LPWStr)]
public string szTableName;
/// <summary>
/// Name of the table from which to inherit base DDL.
/// </summary>
[MarshalAs(UnmanagedType.LPWStr)]
public string szTemplateTableName;
/// <summary>
/// Initial pages to allocate for table.
/// </summary>
public uint ulPages;
/// <summary>
/// Table density.
/// </summary>
public uint ulDensity;
/// <summary>
/// Array of column creation info.
/// </summary>
public NATIVE_COLUMNCREATE* rgcolumncreate;
/// <summary>
/// Number of columns to create.
/// </summary>
public uint cColumns;
/// <summary>
/// Array of indices to create, pointer to <see cref="NATIVE_INDEXCREATE3"/>.
/// </summary>
public IntPtr rgindexcreate;
/// <summary>
/// Number of indices to create.
/// </summary>
public uint cIndexes;
/// <summary>
/// Callback function to use for the table.
/// </summary>
[MarshalAs(UnmanagedType.LPWStr)]
public string szCallback;
/// <summary>
/// Type of the callback function.
/// </summary>
public JET_cbtyp cbtyp;
/// <summary>
/// Table options.
/// </summary>
public uint grbit;
/// <summary>
/// Space allocation, maintenance, and usage hints for default sequential index.
/// </summary>
public NATIVE_SPACEHINTS* pSeqSpacehints;
/// <summary>
/// Space allocation, maintenance, and usage hints for Separated LV tree.
/// </summary>
public NATIVE_SPACEHINTS* pLVSpacehints;
/// <summary>
/// Heuristic size to separate a intrinsic LV from the primary record.
/// </summary>
public uint cbSeparateLV;
/// <summary>
/// Returned tableid.
/// </summary>
public IntPtr tableid;
/// <summary>
/// Count of objects created (columns+table+indexes+callbacks).
/// </summary>
public uint cCreated;
}
/// <summary>
/// Contains the information needed to create a table in an ESE database.
/// </summary>
public partial class JET_TABLECREATE : IContentEquatable<JET_TABLECREATE>, IDeepCloneable<JET_TABLECREATE>
{
/// <summary>
/// Gets the native (interop) version of this object. The following members are
/// NOT converted: <see cref="rgcolumncreate"/>, <see cref="rgindexcreate"/>,
/// <see cref="pSeqSpacehints"/>, and <see cref="pLVSpacehints"/>.
/// </summary>
/// <returns>The native (interop) version of this object.</returns>
internal NATIVE_TABLECREATE4 GetNativeTableCreate4()
{
this.CheckMembersAreValid();
var native = new NATIVE_TABLECREATE4();
native.cbStruct = checked((uint)Marshal.SizeOf(typeof(NATIVE_TABLECREATE4)));
native.szTableName = this.szTableName;
native.szTemplateTableName = this.szTemplateTableName;
native.ulPages = checked((uint)this.ulPages);
native.ulDensity = checked((uint)this.ulDensity);
// native.rgcolumncreate is done at pinvoke time.
native.cColumns = checked((uint)this.cColumns);
// native.rgindexcreate is done at pinvoke time.
native.cIndexes = checked((uint)this.cIndexes);
native.szCallback = this.szCallback;
native.cbtyp = this.cbtyp;
native.grbit = checked((uint)this.grbit);
// native.pSeqSpacehints is done at pinvoke time.
// native.pLVSpacehints is done at pinvoke time.
native.cbSeparateLV = checked((uint)this.cbSeparateLV);
native.tableid = this.tableid.Value;
native.cCreated = checked((uint)this.cCreated);
return native;
}
}
}

View File

@ -1,26 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="LegacyFileNames.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop.Vista
{
/// <summary>
/// Options for LegacyFileNames.
/// </summary>
public enum LegacyFileNames
{
/// <summary>
/// When this option is present then the database engine will use the following naming conventions for its files:
/// o Transaction Log files will use .LOG for their file extension.
/// o Checkpoint files will use .CHK for their file extension.
/// </summary>
ESE98FileNames = 0x00000001,
/// <summary>
/// Preserve the 8.3 naming syntax for as long as possible. (this should not be changed, w/o ensuring there are no log files).
/// </summary>
EightDotThreeSoftCompat = 0x00000002,
}
}

View File

@ -1,273 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="LibraryHelpers.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using System.Threading;
using Microsoft.Isam.Esent.Interop.Implementation;
/// <summary>
/// Contains several helper functions that are useful in the test binary.
/// In particular, it contains functionality that is not available in
/// reduced-functionality environments (such as CoreClr).
/// </summary>
internal static class LibraryHelpers
{
/// <summary>Provides a platform-specific character used to separate directory levels in a path string that reflects a hierarchical file system organization.</summary>
/// <filterpriority>1</filterpriority>
public static readonly char DirectorySeparatorChar = '\\';
/// <summary>Provides a platform-specific alternate character used to separate directory levels in a path string that reflects a hierarchical file system organization.</summary>
/// <filterpriority>1</filterpriority>
public static readonly char AltDirectorySeparatorChar = '/';
/// <summary>
/// Gets an ASCII encoder.
/// </summary>
public static Encoding EncodingASCII
{
get
{
#if MANAGEDESENT_ON_CORECLR
return SlowAsciiEncoding.Encoding;
#else
return Encoding.ASCII;
#endif
}
}
/// <summary>
/// Gets a new ASCII encoder. It's preferred to use EncodingASCII, but some applications (e.g. tests)
/// may want a different Encoding object.
/// </summary>
public static Encoding NewEncodingASCII
{
get
{
#if MANAGEDESENT_ON_CORECLR
return new SlowAsciiEncoding();
#else
return new ASCIIEncoding();
#endif
}
}
// This should be dead code when running on Core CLR; This is only called by
// GetIndexInfoFromIndexlist() when called on a pre-Win8 system, and Core CLR
// is only on Win8 anyway.
#if !MANAGEDESENT_ON_CORECLR
/// <summary>
/// Creates a CultureInfo object when given the LCID.
/// </summary>
/// <param name="lcid">
/// The lcid passed in.
/// </param>
/// <returns>
/// A CultureInfo object.
/// </returns>
public static CultureInfo CreateCultureInfoByLcid(int lcid)
{
return new CultureInfo(lcid);
}
#endif // !MANAGEDESENT_ON_CORECLR
/// <summary>
/// Allocates memory on the native heap.
/// </summary>
/// <returns>A pointer to native memory.</returns>
/// <param name="size">The size of the memory desired.</param>
public static IntPtr MarshalAllocHGlobal(int size)
{
#if MANAGEDESENT_ON_CORECLR && !MANAGEDESENT_ON_WSA
return Win32.NativeMethods.LocalAlloc(0, new UIntPtr((uint)size));
#else
return Marshal.AllocHGlobal(size);
#endif
}
/// <summary>
/// Frees memory that was allocated on the native heap.
/// </summary>
/// <param name="buffer">A pointer to native memory.</param>
public static void MarshalFreeHGlobal(IntPtr buffer)
{
#if MANAGEDESENT_ON_CORECLR && !MANAGEDESENT_ON_WSA
Win32.NativeMethods.LocalFree(buffer);
#else
Marshal.FreeHGlobal(buffer);
#endif
}
/// <summary>Copies the contents of a managed <see cref="T:System.String" /> into unmanaged memory.</summary>
/// <returns>The address, in unmanaged memory, to where the <paramref name="managedString" /> was copied, or 0 if <paramref name="managedString" /> is null.</returns>
/// <param name="managedString">A managed string to be copied.</param>
/// <exception cref="T:System.OutOfMemoryException">The method could not allocate enough native heap memory.</exception>
/// <exception cref="T:System.ArgumentOutOfRangeException">The <paramref name="managedString" /> parameter exceeds the maximum length allowed by the operating system.</exception>
public static IntPtr MarshalStringToHGlobalUni(string managedString)
{
#if MANAGEDESENT_ON_CORECLR && !MANAGEDESENT_ON_WSA
return MyStringToHGlobalUni(managedString);
#else
return Marshal.StringToHGlobalUni(managedString);
#endif
}
/// <summary>
/// Retrieves the managed ID of the current thread.
/// </summary>
/// <returns>The ID of the current thread.</returns>
public static int GetCurrentManagedThreadId()
{
#if MANAGEDESENT_ON_CORECLR
return Environment.CurrentManagedThreadId;
#else
return Thread.CurrentThread.ManagedThreadId;
#endif
}
/// <summary>
/// Cancels an <see cref="M:System.Threading.Thread.Abort(System.Object)"/> requested for the current thread.
/// </summary>
/// <exception cref="T:System.Threading.ThreadStateException">Abort was not invoked on the current thread. </exception><exception cref="T:System.Security.SecurityException">The caller does not have the required security permission for the current thread. </exception><filterpriority>2</filterpriority><PermissionSet><IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="ControlThread"/></PermissionSet>
public static void ThreadResetAbort()
{
#if MANAGEDESENT_ON_CORECLR
// Do nothing.
#else
Thread.ResetAbort();
#endif
}
// FUTURE-2013/12/16-martinc. It appears that all of this hacking for running on Core CLR may no longer be necessary.
// We initially ported to an early version of Core CLR that had a lot of functionality missing. By the time
// Windows Store Apps came out in Windows 8, many of these functions were added back.
#if MANAGEDESENT_ON_CORECLR && !MANAGEDESENT_ON_WSA
// System.Runtime.InteropServices.Marshal
/// <summary>Copies the contents of a managed <see cref="T:System.String" /> into unmanaged memory.</summary>
/// <returns>The address, in unmanaged memory, to where the <paramref name="managedString" /> was copied, or 0 if <paramref name="managedString" /> is null.</returns>
/// <param name="managedString">A managed string to be copied.</param>
/// <exception cref="T:System.OutOfMemoryException">The method could not allocate enough native heap memory.</exception>
/// <exception cref="T:System.ArgumentOutOfRangeException">The <paramref name="managedString" /> parameter exceeds the maximum length allowed by the operating system.</exception>
[SecurityCritical]
private static unsafe IntPtr MyStringToHGlobalUni(string managedString)
{
if (managedString == null)
{
return IntPtr.Zero;
}
int charCountWithNull = managedString.Length + 1;
int byteCount = charCountWithNull * sizeof(char);
if (byteCount < managedString.Length)
{
throw new ArgumentOutOfRangeException("managedString");
}
UIntPtr sizetdwBytes = new UIntPtr((uint)byteCount);
IntPtr rawBuffer = Win32.NativeMethods.LocalAlloc(0, sizetdwBytes);
if (rawBuffer == IntPtr.Zero)
{
throw new OutOfMemoryException();
}
fixed (char* sourcePointer = managedString)
{
byte* destPointer = (byte*)rawBuffer;
var unicodeEncoding = new System.Text.UnicodeEncoding();
int bytesWritten = unicodeEncoding.GetBytes(sourcePointer, charCountWithNull, destPointer, byteCount);
}
return rawBuffer;
}
#endif // MANAGEDESENT_ON_CORECLR && !MANAGEDESENT_ON_WSA
/// <summary>Returns a <see cref="T:System.DateTime" /> equivalent to the specified OLE Automation Date.</summary>
/// <returns>A <see cref="T:System.DateTime" /> that represents the same date and time as <paramref name="d" />.</returns>
/// <param name="d">An OLE Automation Date value. </param>
/// <exception cref="T:System.ArgumentException">The date is not a valid OLE Automation Date value. </exception>
/// <filterpriority>1</filterpriority>
public static DateTime FromOADate(double d)
{
#if MANAGEDESENT_ON_CORECLR
return new DateTime(DoubleDateToTicks(d), DateTimeKind.Unspecified);
#else
return DateTime.FromOADate(d);
#endif
}
#if MANAGEDESENT_ON_CORECLR
/// <summary>
/// Copied from the reflected implementation.
/// </summary>
/// <param name="value">The date, as a 64bit integer.</param>
/// <returns>The date, as a double representation.</returns>
internal static double TicksToOADate(long value)
{
if (value == 0L)
{
return 0.0;
}
if (value < 864000000000L)
{
value += 599264352000000000L;
}
if (value < 31241376000000000L)
{
throw new OverflowException();
}
long num = (value - 599264352000000000L) / 10000L;
if (num < 0L)
{
long num2 = num % 86400000L;
if (num2 != 0L)
{
num -= (86400000L + num2) * 2L;
}
}
return (double)num / 86400000.0;
}
/// <summary>
/// Copied from the reflected implementation.
/// </summary>
/// <param name="value">The date, as a double representation.</param>
/// <returns>The date, as a 64bit integer.</returns>
internal static long DoubleDateToTicks(double value)
{
if (value >= 2958466.0 || value <= -657435.0)
{
throw new ArgumentException("value does not represent a valid date", "value");
}
long num = (long)((value * 86400000.0) + ((value >= 0.0) ? 0.5 : -0.5));
if (num < 0L)
{
num -= (num % 86400000L) * 2L;
}
num += 59926435200000L;
if (num < 0L || num >= 315537897600000L)
{
throw new ArgumentException("value does not represent a valid date", "value");
}
return num * 10000L;
}
#endif
}
}

View File

@ -1,321 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="MakeKeyHelpers.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Text;
/// <summary>
/// Helper methods for the ESENT API. These do data conversion for
/// JetMakeKey.
/// </summary>
public static partial class Api
{
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, byte[] data, MakeKeyGrbit grbit)
{
if (null == data)
{
Api.JetMakeKey(sesid, tableid, null, 0, grbit);
}
else if (0 == data.Length)
{
Api.JetMakeKey(sesid, tableid, data, data.Length, grbit | MakeKeyGrbit.KeyDataZeroLength);
}
else
{
Api.JetMakeKey(sesid, tableid, data, data.Length, grbit);
}
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="encoding">The encoding used to convert the string.</param>
/// <param name="grbit">Key options.</param>
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, string data, Encoding encoding, MakeKeyGrbit grbit)
{
CheckEncodingIsValid(encoding);
if (null == data)
{
Api.JetMakeKey(sesid, tableid, null, 0, grbit);
}
else if (0 == data.Length)
{
Api.JetMakeKey(sesid, tableid, null, 0, grbit | MakeKeyGrbit.KeyDataZeroLength);
}
else if (Encoding.Unicode == encoding)
{
// Optimization for Unicode strings
unsafe
{
fixed (char* buffer = data)
{
Api.JetMakeKey(sesid, tableid, new IntPtr(buffer), checked(data.Length * sizeof(char)), grbit);
}
}
}
else
{
#if MANAGEDESENT_ON_WSA
// Encoding.GetBytes(char*, int, byte*, int) overload is missing in new Windows UI.
// So we can't use the ColumnCache. We'll just use a different GetBytes() overload.
byte[] buffer = encoding.GetBytes(data);
Api.JetMakeKey(sesid, tableid, buffer, buffer.Length, grbit);
#else
// Convert the string using a cached column buffer. The column buffer is far larger
// than the maximum key size, so any data truncation here won't matter.
byte[] buffer = null;
try
{
buffer = Caches.ColumnCache.Allocate();
int dataSize;
unsafe
{
fixed (char* chars = data)
fixed (byte* bytes = buffer)
{
dataSize = encoding.GetBytes(chars, data.Length, bytes, buffer.Length);
}
}
JetMakeKey(sesid, tableid, buffer, dataSize, grbit);
}
finally
{
if (buffer != null)
{
Caches.ColumnCache.Free(ref buffer);
}
}
#endif
}
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, bool data, MakeKeyGrbit grbit)
{
byte b = data ? (byte)0xff : (byte)0x0;
Api.MakeKey(sesid, tableid, b, grbit);
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, byte data, MakeKeyGrbit grbit)
{
unsafe
{
const int DataSize = sizeof(byte);
var pointer = new IntPtr(&data);
Api.JetMakeKey(sesid, tableid, pointer, DataSize, grbit);
}
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, short data, MakeKeyGrbit grbit)
{
unsafe
{
const int DataSize = sizeof(short);
var pointer = new IntPtr(&data);
Api.JetMakeKey(sesid, tableid, pointer, DataSize, grbit);
}
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, int data, MakeKeyGrbit grbit)
{
unsafe
{
const int DataSize = sizeof(int);
var pointer = new IntPtr(&data);
Api.JetMakeKey(sesid, tableid, pointer, DataSize, grbit);
}
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, long data, MakeKeyGrbit grbit)
{
unsafe
{
const int DataSize = sizeof(long);
var pointer = new IntPtr(&data);
Api.JetMakeKey(sesid, tableid, pointer, DataSize, grbit);
}
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, Guid data, MakeKeyGrbit grbit)
{
unsafe
{
const int DataSize = 16 /* sizeof(Guid) */;
var pointer = new IntPtr(&data);
Api.JetMakeKey(sesid, tableid, pointer, DataSize, grbit);
}
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, DateTime data, MakeKeyGrbit grbit)
{
Api.MakeKey(sesid, tableid, data.ToOADate(), grbit);
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, float data, MakeKeyGrbit grbit)
{
unsafe
{
const int DataSize = sizeof(float);
var pointer = new IntPtr(&data);
Api.JetMakeKey(sesid, tableid, pointer, DataSize, grbit);
}
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, double data, MakeKeyGrbit grbit)
{
unsafe
{
const int DataSize = sizeof(double);
var pointer = new IntPtr(&data);
Api.JetMakeKey(sesid, tableid, pointer, DataSize, grbit);
}
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
[CLSCompliant(false)]
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, ushort data, MakeKeyGrbit grbit)
{
unsafe
{
const int DataSize = sizeof(ushort);
var pointer = new IntPtr(&data);
Api.JetMakeKey(sesid, tableid, pointer, DataSize, grbit);
}
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
[CLSCompliant(false)]
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, uint data, MakeKeyGrbit grbit)
{
unsafe
{
const int DataSize = sizeof(uint);
var pointer = new IntPtr(&data);
Api.JetMakeKey(sesid, tableid, pointer, DataSize, grbit);
}
}
/// <summary>
/// Constructs a search key that may then be used by <see cref="JetSeek"/>
/// and <see cref="JetSetIndexRange"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to create the key on.</param>
/// <param name="data">Column data for the current key column of the current index.</param>
/// <param name="grbit">Key options.</param>
[CLSCompliant(false)]
public static void MakeKey(JET_SESID sesid, JET_TABLEID tableid, ulong data, MakeKeyGrbit grbit)
{
unsafe
{
const int DataSize = sizeof(ulong);
var pointer = new IntPtr(&data);
Api.JetMakeKey(sesid, tableid, pointer, DataSize, grbit);
}
}
}
}

View File

@ -1,151 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="MemoryCache.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
using System.Threading;
/// <summary>
/// Cache allocated chunks of memory that are needed for very short periods
/// of time. The memory is not zeroed on allocation.
/// </summary>
internal sealed class MemoryCache
{
/// <summary>
/// A zero-length array that should be used whenever we want to return one.
/// </summary>
private static readonly byte[] ZeroLengthArray = new byte[0];
/// <summary>
/// Default size for newly allocated buffers.
/// </summary>
private readonly int bufferSize;
/// <summary>
/// Currently cached buffers.
/// </summary>
private readonly byte[][] cachedBuffers;
/// <summary>
/// Initializes a new instance of the <see cref="MemoryCache"/> class.
/// </summary>
/// <param name="bufferSize">
/// The size of the buffers to cache.
/// </param>
/// <param name="maxCachedBuffers">
/// The maximum number of buffers to cache.
/// </param>
public MemoryCache(int bufferSize, int maxCachedBuffers)
{
this.bufferSize = bufferSize;
this.cachedBuffers = new byte[maxCachedBuffers][];
}
/// <summary>
/// Gets the size of the buffers that this cache returns.
/// </summary>
public int BufferSize
{
get
{
return this.bufferSize;
}
}
/// <summary>
/// Creates a new array containing a copy of 'length' bytes of data.
/// </summary>
/// <param name="data">The data to copy.</param>
/// <param name="length">The length of data to copy.</param>
/// <returns>An array containing the first length bytes of data.</returns>
public static byte[] Duplicate(byte[] data, int length)
{
Debug.Assert(data.Length >= length, "length parameter is too long");
if (0 == length)
{
return ZeroLengthArray;
}
var output = new byte[length];
Buffer.BlockCopy(data, 0, output, 0, length);
return output;
}
/// <summary>
/// Allocates a chunk of memory. If memory is cached it is returned. If no memory
/// is cached then it is allocated. Check the size of the returned buffer to determine
/// how much memory was allocated.
/// </summary>
/// <returns>A new memory buffer.</returns>
public byte[] Allocate()
{
int offset = this.GetStartingOffset();
for (int i = 0; i < this.cachedBuffers.Length; ++i)
{
int index = (i + offset) % this.cachedBuffers.Length;
byte[] buffer = Interlocked.Exchange(ref this.cachedBuffers[index], null);
if (null != buffer)
{
return buffer;
}
}
return new byte[this.bufferSize];
}
/// <summary>
/// Frees an unused buffer. This may be added to the cache.
/// </summary>
/// <param name="data">The memory to free.</param>
public void Free(ref byte[] data)
{
if (null == data)
{
throw new ArgumentNullException("data");
}
if (data.Length != this.bufferSize)
{
throw new ArgumentOutOfRangeException("data", data.Length, "buffer is not correct size for this MemoryCache");
}
int offset = this.GetStartingOffset();
// The buffers are garbage collected so we don't need to make Free()
// completely safe. In a multi-threaded situation we may see a null
// slot and then overwrite a buffer which was just freed into the slot.
// That will cause us to lose a buffer which could have been placed
// in a different slot, but in return we can do the Free() without
// expensive interlocked operations.
for (int i = 0; i < this.cachedBuffers.Length; ++i)
{
int index = (i + offset) % this.cachedBuffers.Length;
if (null == this.cachedBuffers[index])
{
this.cachedBuffers[index] = data;
break;
}
}
data = null;
}
/// <summary>
/// Get the offset in the cached buffers array to start allocating or freeing
/// buffers to. This is done so that all threads don't start operating on
/// slot zero, which would increase contention.
/// </summary>
/// <returns>The starting offset for Allocate/Free operations.</returns>
private int GetStartingOffset()
{
// Using the current CPU number would be ideal, but there doesn't seem to
// be a cheap way to get that information in managed code.
return LibraryHelpers.GetCurrentManagedThreadId() % this.cachedBuffers.Length;
}
}
}

View File

@ -1,294 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="MetaDataHelpers.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using Microsoft.Isam.Esent.Interop.Implementation;
/// <summary>
/// Helper methods for the ESENT API. These methods deal with database
/// meta-data.
/// </summary>
public static partial class Api
{
#region Simpler API. Overloads that omit unused/obsolete parameters.
/// <summary>
/// Initialize a new ESENT session.
/// </summary>
/// <param name="instance">The initialized instance to create the session in.</param>
/// <param name="sesid">Returns the created session.</param>
public static void BeginSession(JET_INSTANCE instance, out JET_SESID sesid)
{
Api.JetBeginSession(instance, out sesid, null, null);
}
/// <summary>
/// Creates and attaches a database file.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="database">The path to the database file to create.</param>
/// <param name="dbid">Returns the dbid of the new database.</param>
/// <param name="grbit">Database creation options.</param>
public static void CreateDatabase(JET_SESID sesid, string database, out JET_DBID dbid, CreateDatabaseGrbit grbit)
{
Api.JetCreateDatabase(sesid, database, null, out dbid, grbit);
}
/// <summary>
/// Opens a database previously attached with <see cref="JetAttachDatabase"/>,
/// for use with a database session. This function can be called multiple times
/// for the same database.
/// </summary>
/// <param name="sesid">The session that is opening the database.</param>
/// <param name="database">The database to open.</param>
/// <param name="dbid">Returns the dbid of the attached database.</param>
/// <param name="grbit">Open database options.</param>
/// <returns>An ESENT warning code.</returns>
public static JET_wrn OpenDatabase(
JET_SESID sesid,
string database,
out JET_DBID dbid,
OpenDatabaseGrbit grbit)
{
return Api.JetOpenDatabase(sesid, database, null, out dbid, grbit);
}
/// <summary>
/// Opens a cursor on a previously created table.
/// </summary>
/// <param name="sesid">The database session to use.</param>
/// <param name="dbid">The database to open the table in.</param>
/// <param name="tablename">The name of the table to open.</param>
/// <param name="grbit">Table open options.</param>
/// <param name="tableid">Returns the opened table.</param>
/// <returns>An ESENT warning.</returns>
public static JET_wrn OpenTable(
JET_SESID sesid,
JET_DBID dbid,
string tablename,
OpenTableGrbit grbit,
out JET_TABLEID tableid)
{
return Api.JetOpenTable(sesid, dbid, tablename, null, 0, grbit, out tableid);
}
#endregion
/// <summary>
/// Try to open a table.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="dbid">The database to look for the table in.</param>
/// <param name="tablename">The name of the table.</param>
/// <param name="grbit">Table open options.</param>
/// <param name="tableid">Returns the opened tableid.</param>
/// <returns>True if the table was opened, false if the table doesn't exist.</returns>
public static bool TryOpenTable(
JET_SESID sesid,
JET_DBID dbid,
string tablename,
OpenTableGrbit grbit,
out JET_TABLEID tableid)
{
var err = (JET_err)Impl.JetOpenTable(sesid, dbid, tablename, null, 0, grbit, out tableid);
if (JET_err.ObjectNotFound == err)
{
return false;
}
Api.Check((int)err);
Debug.Assert(err >= JET_err.Success, "Exception should have been thrown in case of error");
return true;
}
/// <summary>
/// Creates a dictionary which maps column names to their column IDs.
/// </summary>
/// <param name="sesid">The sesid to use.</param>
/// <param name="tableid">The table to retrieve the information for.</param>
/// <returns>A dictionary mapping column names to column IDs.</returns>
public static IDictionary<string, JET_COLUMNID> GetColumnDictionary(JET_SESID sesid, JET_TABLEID tableid)
{
JET_COLUMNLIST columnlist;
JetGetTableColumnInfo(sesid, tableid, string.Empty, out columnlist);
// As of Sep 2015, JetGetColumnInfoW is only called for Win8+. Even though Unicode should have
// worked in Win7, it wasn't reliable until Win8.
Encoding encodingOfTextColumns = EsentVersion.SupportsWindows8Features ? Encoding.Unicode : LibraryHelpers.EncodingASCII;
try
{
// esent treats column names as case-insensitive, so we want the dictionary to be case insensitive as well
var dict = new Dictionary<string, JET_COLUMNID>(
columnlist.cRecord, StringComparer.OrdinalIgnoreCase);
if (columnlist.cRecord > 0)
{
if (Api.TryMoveFirst(sesid, columnlist.tableid))
{
do
{
string name = RetrieveColumnAsString(
sesid,
columnlist.tableid,
columnlist.columnidcolumnname,
encodingOfTextColumns,
RetrieveColumnGrbit.None);
name = StringCache.TryToIntern(name);
var columnidValue =
(uint)RetrieveColumnAsUInt32(sesid, columnlist.tableid, columnlist.columnidcolumnid);
var columnid = new JET_COLUMNID { Value = columnidValue };
dict.Add(name, columnid);
}
while (TryMoveNext(sesid, columnlist.tableid));
}
}
return dict;
}
finally
{
// Close the temporary table used to return the results
JetCloseTable(sesid, columnlist.tableid);
}
}
/// <summary>
/// Get the columnid of the specified column.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The table containing the column.</param>
/// <param name="columnName">The name of the column.</param>
/// <returns>The id of the column.</returns>
public static JET_COLUMNID GetTableColumnid(JET_SESID sesid, JET_TABLEID tableid, string columnName)
{
JET_COLUMNDEF columndef;
JetGetTableColumnInfo(sesid, tableid, columnName, out columndef);
return columndef.columnid;
}
/// <summary>
/// Iterates over all the columns in the table, returning information about each one.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The table to retrieve column information for.</param>
/// <returns>An iterator over ColumnInfo for each column in the table.</returns>
public static IEnumerable<ColumnInfo> GetTableColumns(JET_SESID sesid, JET_TABLEID tableid)
{
return new GenericEnumerable<ColumnInfo>(() => new TableidColumnInfoEnumerator(sesid, tableid));
}
/// <summary>
/// Iterates over all the columns in the table, returning information about each one.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="dbid">The database containing the table.</param>
/// <param name="tablename">The name of the table.</param>
/// <returns>An iterator over ColumnInfo for each column in the table.</returns>
public static IEnumerable<ColumnInfo> GetTableColumns(JET_SESID sesid, JET_DBID dbid, string tablename)
{
if (null == tablename)
{
throw new ArgumentNullException("tablename");
}
return new GenericEnumerable<ColumnInfo>(() => new TableColumnInfoEnumerator(sesid, dbid, tablename));
}
/// <summary>
/// Iterates over all the indexes in the table, returning information about each one.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The table to retrieve index information for.</param>
/// <returns>An iterator over an IndexInfo for each index in the table.</returns>
public static IEnumerable<IndexInfo> GetTableIndexes(JET_SESID sesid, JET_TABLEID tableid)
{
return new GenericEnumerable<IndexInfo>(() => new TableidIndexInfoEnumerator(sesid, tableid));
}
/// <summary>
/// Iterates over all the indexs in the table, returning information about each one.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="dbid">The database containing the table.</param>
/// <param name="tablename">The name of the table.</param>
/// <returns>An iterator over an IndexInfo for each index in the table.</returns>
public static IEnumerable<IndexInfo> GetTableIndexes(JET_SESID sesid, JET_DBID dbid, string tablename)
{
if (null == tablename)
{
throw new ArgumentNullException("tablename");
}
return new GenericEnumerable<IndexInfo>(() => new TableIndexInfoEnumerator(sesid, dbid, tablename));
}
/// <summary>
/// Returns the names of the tables in the database.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="dbid">The database containing the table.</param>
/// <returns>An iterator over the names of the tables in the database.</returns>
public static IEnumerable<string> GetTableNames(JET_SESID sesid, JET_DBID dbid)
{
return new GenericEnumerable<string>(() => new TableNameEnumerator(sesid, dbid));
}
/// <summary>
/// Retrieves information about indexes on a table.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The table to retrieve index information about.</param>
/// <param name="indexname">The name of the index.</param>
/// <param name="result">Filled in with information about indexes on the table.</param>
/// <param name="infoLevel">The type of information to retrieve.</param>
/// <returns>true if there was no error, false if the index wasn't found. Throws for other Jet errors.</returns>
public static bool TryJetGetTableIndexInfo(
JET_SESID sesid,
JET_TABLEID tableid,
string indexname,
out JET_INDEXID result,
JET_IdxInfo infoLevel)
{
int err = Impl.JetGetTableIndexInfo(sesid, tableid, indexname, out result, infoLevel);
if ((JET_err)err == JET_err.IndexNotFound)
{
return false;
}
Api.Check(err);
return true;
}
/// <summary>
/// Determines the name of the current index of a given cursor.
/// </summary>
/// <remarks>
/// This name is also used to later re-select that index as the current index using
/// <see cref="JetSetCurrentIndex"/>. It can also be used to discover the properties of that index using
/// JetGetTableIndexInfo.
///
/// The returned name of the index will be null if the current index is the clustered index and no primary
/// index was explicitly defined.
/// </remarks>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to get the index name for.</param>
/// <returns>Returns the name of the index.</returns>
public static string JetGetCurrentIndex(JET_SESID sesid, JET_TABLEID tableid)
{
string indexName;
Api.JetGetCurrentIndex(sesid, tableid, out indexName, SystemParameters.NameMost);
return string.IsNullOrEmpty(indexName) ? null : indexName;
}
}
}

View File

@ -1,244 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="MoveHelpers.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
/// <summary>
/// Helper methods for the ESENT API. These aren't interop versions
/// of the API, but encapsulate very common uses of the functions.
/// </summary>
public static partial class Api
{
/// <summary>
/// Position the cursor before the first record in the table. A
/// subsequent move next will position the cursor on the first
/// record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The table to position.</param>
public static void MoveBeforeFirst(JET_SESID sesid, JET_TABLEID tableid)
{
Api.TryMoveFirst(sesid, tableid);
Api.TryMovePrevious(sesid, tableid);
}
/// <summary>
/// Position the cursor after the last record in the table. A
/// subsequent move previous will position the cursor on the
/// last record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The table to position.</param>
public static void MoveAfterLast(JET_SESID sesid, JET_TABLEID tableid)
{
Api.TryMoveLast(sesid, tableid);
Api.TryMoveNext(sesid, tableid);
}
/// <summary>
/// Try to navigate through an index. If the navigation succeeds this
/// method returns true. If there is no record to navigate to this
/// method returns false; an exception will be thrown for other errors.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to position.</param>
/// <param name="move">The direction to move in.</param>
/// <param name="grbit">Move options.</param>
/// <returns>True if the move was successful.</returns>
public static bool TryMove(JET_SESID sesid, JET_TABLEID tableid, JET_Move move, MoveGrbit grbit)
{
var err = (JET_err)Impl.JetMove(sesid, tableid, (int)move, grbit);
if (JET_err.NoCurrentRecord == err)
{
return false;
}
Api.Check((int)err);
Debug.Assert(err >= JET_err.Success, "Exception should have been thrown in case of error");
return true;
}
/// <summary>
/// Try to move to the first record in the table. If the table is empty this
/// returns false, if a different error is encountered an exception is thrown.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to position.</param>
/// <returns>True if the move was successful.</returns>
public static bool TryMoveFirst(JET_SESID sesid, JET_TABLEID tableid)
{
return TryMove(sesid, tableid, JET_Move.First, MoveGrbit.None);
}
/// <summary>
/// Try to move to the last record in the table. If the table is empty this
/// returns false, if a different error is encountered an exception is thrown.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to position.</param>
/// <returns>True if the move was successful.</returns>
public static bool TryMoveLast(JET_SESID sesid, JET_TABLEID tableid)
{
return TryMove(sesid, tableid, JET_Move.Last, MoveGrbit.None);
}
/// <summary>
/// Try to move to the next record in the table. If there is not a next record
/// this returns false, if a different error is encountered an exception is thrown.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to position.</param>
/// <returns>True if the move was successful.</returns>
public static bool TryMoveNext(JET_SESID sesid, JET_TABLEID tableid)
{
return TryMove(sesid, tableid, JET_Move.Next, MoveGrbit.None);
}
/// <summary>
/// Try to move to the previous record in the table. If there is not a previous record
/// this returns false, if a different error is encountered an exception is thrown.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to position.</param>
/// <returns>True if the move was successful.</returns>
public static bool TryMovePrevious(JET_SESID sesid, JET_TABLEID tableid)
{
return TryMove(sesid, tableid, JET_Move.Previous, MoveGrbit.None);
}
/// <summary>
/// Efficiently positions a cursor to an index entry that matches the search
/// criteria specified by the search key in that cursor and the specified
/// inequality. A search key must have been previously constructed using JetMakeKey.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to position.</param>
/// <param name="grbit">Seek option.</param>
/// <returns>True if a record matching the criteria was found.</returns>
public static bool TrySeek(JET_SESID sesid, JET_TABLEID tableid, SeekGrbit grbit)
{
var err = (JET_err)Impl.JetSeek(sesid, tableid, grbit);
if (JET_err.RecordNotFound == err)
{
return false;
}
Api.Check((int)err);
Debug.Assert(err >= JET_err.Success, "Exception should have been thrown in case of error");
return true;
}
/// <summary>
/// Temporarily limits the set of index entries that the cursor can walk using
/// JetMove to those starting from the current index entry and ending at the index
/// entry that matches the search criteria specified by the search key in that cursor
/// and the specified bound criteria. A search key must have been previously constructed
/// using JetMakeKey. Returns true if the index range is non-empty, false otherwise.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to position.</param>
/// <param name="grbit">Seek option.</param>
/// <returns>True if the seek was successful.</returns>
public static bool TrySetIndexRange(JET_SESID sesid, JET_TABLEID tableid, SetIndexRangeGrbit grbit)
{
var err = (JET_err)Impl.JetSetIndexRange(sesid, tableid, grbit);
if (JET_err.NoCurrentRecord == err)
{
return false;
}
Api.Check((int)err);
Debug.Assert(err >= JET_err.Success, "Exception should have been thrown in case of error");
return true;
}
/// <summary>
/// Removes an index range created with <see cref="JetSetIndexRange"/> or
/// <see cref="TrySetIndexRange"/>. If no index range is present this
/// method does nothing.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to remove the index range on.</param>
public static void ResetIndexRange(JET_SESID sesid, JET_TABLEID tableid)
{
var err = (JET_err)Impl.JetSetIndexRange(sesid, tableid, SetIndexRangeGrbit.RangeRemove);
if (JET_err.InvalidOperation == err)
{
// this error is expected if there isn't currently an index range
return;
}
Api.Check((int)err);
return;
}
/// <summary>
/// Intersect a group of index ranges and return the bookmarks of the records which are found
/// in all the index ranges.
/// Also see <see cref="JetIntersectIndexes"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableids">
/// The tableids to use. Each tableid must be from a different index on the same table and
/// have an active index range. Use <see cref="JetSetIndexRange"/>
/// to create an index range.
/// </param>
/// <returns>
/// The bookmarks of the records which are found in all the index ranges. The bookmarks
/// are returned in primary key order.
/// </returns>
public static IEnumerable<byte[]> IntersectIndexes(JET_SESID sesid, params JET_TABLEID[] tableids)
{
if (null == tableids)
{
throw new ArgumentNullException("tableids");
}
var ranges = new JET_INDEXRANGE[tableids.Length];
for (int i = 0; i < tableids.Length; ++i)
{
ranges[i] = new JET_INDEXRANGE { tableid = tableids[i] };
}
return new GenericEnumerable<byte[]>(() => new IntersectIndexesEnumerator(sesid, ranges));
}
/// <summary>
/// Positions a cursor to an index entry for the record that is associated with
/// the specified bookmark. The bookmark can be used with any index defined over
/// a table. The bookmark for a record can be retrieved using <see cref="JetGetBookmark"/>.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to position.</param>
/// <param name="bookmark">The bookmark used to position the cursor.</param>
/// <param name="bookmarkSize">The size of the bookmark.</param>
/// <returns>True if a record matching the bookmark was found.</returns>
public static bool TryGotoBookmark(JET_SESID sesid, JET_TABLEID tableid, byte[] bookmark, int bookmarkSize)
{
var err = (JET_err)Impl.JetGotoBookmark(sesid, tableid, bookmark, bookmarkSize);
// Return false if the record no longer exists.
if (JET_err.RecordDeleted == err)
{
return false;
}
// Return false if there is no entry for this record on the current (secondary) index.
if (JET_err.NoCurrentRecord == err)
{
return false;
}
Api.Check((int)err);
Debug.Assert(err >= JET_err.Success, "Exception should have been thrown in case of error");
return true;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,53 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="ObjectInfoFlags.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
/// <summary>
/// Flags for ESENT objects (tables). Used in <see cref="JET_OBJECTINFO"/>.
/// </summary>
[Flags]
public enum ObjectInfoFlags
{
/// <summary>
/// Default options.
/// </summary>
None = 0,
/// <summary>
/// Object is for internal use only.
/// </summary>
System = -2147483648, // 0x80000000
// It's possible to use bit shift to avoid triggering fxcop CA2217.
// System = (long)0x1L << 31, // 0x80000000;
// (http://social.msdn.microsoft.com/Forums/en-US/vstscode/thread/a44aa5c1-c62a-46b7-8009-dc46ba21ba93)
// But we don't want to change the type of the enum to a long.
/// <summary>
/// Table's DDL is fixed.
/// </summary>
TableFixedDDL = 0x40000000,
/// <summary>
/// Table's DDL is inheritable.
/// </summary>
TableTemplate = 0x20000000,
/// <summary>
/// Table's DDL is inherited from a template table.
/// </summary>
TableDerived = 0x10000000,
/// <summary>
/// Fixed or variable columns in derived tables (so that fixed or variable
/// columns can be added to the template in the future).
/// Used in conjunction with <see cref="TableTemplate"/>.
/// </summary>
TableNoFixedVarColumnsInDerivedTables = 0x04000000,
}
}

View File

@ -1,52 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="ObsoleteApi.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
/// <summary>
/// API members that are marked as obsolete.
/// </summary>
public static partial class Api
{
/// <summary>
/// Retrieves information about indexes on a table.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="dbid">The database to use.</param>
/// <param name="tablename">The name of the table to retrieve index information about.</param>
/// <param name="ignored">This parameter is ignored.</param>
/// <param name="indexlist">Filled in with information about indexes on the table.</param>
[Obsolete("Use the overload that takes a JET_IdxInfo parameter, passing in JET_IdxInfo.List")]
public static void JetGetIndexInfo(
JET_SESID sesid,
JET_DBID dbid,
string tablename,
string ignored,
out JET_INDEXLIST indexlist)
{
Api.JetGetIndexInfo(sesid, dbid, tablename, ignored, out indexlist, JET_IdxInfo.List);
}
/// <summary>
/// Retrieves information about indexes on a table.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The table to retrieve index information about.</param>
/// <param name="indexname">This parameter is ignored.</param>
/// <param name="indexlist">Filled in with information about indexes on the table.</param>
[Obsolete("Use the overload that takes a JET_IdxInfo parameter, passing in JET_IdxInfo.List")]
public static void JetGetTableIndexInfo(
JET_SESID sesid,
JET_TABLEID tableid,
string indexname,
out JET_INDEXLIST indexlist)
{
Api.JetGetTableIndexInfo(sesid, tableid, indexname, out indexlist, JET_IdxInfo.List);
}
}
}

View File

@ -1,44 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="OnlineMaintenanceHelpers.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using Microsoft.Isam.Esent.Interop.Implementation;
/// <summary>
/// Helper methods for the ESENT API. These methods deal with database
/// meta-data.
/// </summary>
public static partial class Api
{
/// <summary>
/// Starts and stops database defragmentation tasks that improves data
/// organization within a database.
/// </summary>
/// <param name="sesid">The session to use for the call.</param>
/// <param name="dbid">The database to be defragmented.</param>
/// <param name="tableName">
/// Under some options defragmentation is performed for the entire database described by the given
/// database ID, and other options (such as <see cref="Windows7.Windows7Grbits.DefragmentBTree"/>) require
/// the name of the table to defragment.
/// </param>
/// <param name="grbit">Defragmentation options.</param>
/// <returns>A warning code.</returns>
/// <seealso cref="Api.JetDefragment"/>
public static JET_wrn Defragment(
JET_SESID sesid,
JET_DBID dbid,
string tableName,
DefragGrbit grbit)
{
return Api.Check(Impl.Defragment(sesid, dbid, tableName, grbit));
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,50 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="Server2003Api.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop.Server2003
{
/// <summary>
/// APIs that have been added to the Windows Server 2003 version of ESENT.
/// </summary>
public static class Server2003Api
{
#if !MANAGEDESENT_ON_WSA
/// <summary>
/// Notifies the engine that it can resume normal IO operations after a
/// freeze period ended with a failed snapshot.
/// </summary>
/// <param name="snapid">Identifier of the snapshot session.</param>
/// <param name="grbit">Options for this call.</param>
public static void JetOSSnapshotAbort(JET_OSSNAPID snapid, SnapshotAbortGrbit grbit)
{
Api.Check(Api.Impl.JetOSSnapshotAbort(snapid, grbit));
}
#endif // !MANAGEDESENT_ON_WSA
/// <summary>
/// The JetUpdate function performs an update operation including inserting a new row into
/// a table or updating an existing row. Deleting a table row is performed by calling
/// <see cref="Api.JetDelete"/>.
/// </summary>
/// <param name="sesid">The session which started the update.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="bookmark">Returns the bookmark of the updated record. This can be null.</param>
/// <param name="bookmarkSize">The size of the bookmark buffer.</param>
/// <param name="actualBookmarkSize">Returns the actual size of the bookmark.</param>
/// <param name="grbit">Update options.</param>
/// <remarks>
/// JetUpdate is the final step in performing an insert or an update. The update is begun by
/// calling <see cref="Api.JetPrepareUpdate"/> and then by calling
/// <see cref="Api.JetSetColumn(JET_SESID,JET_TABLEID,JET_COLUMNID,byte[],int,SetColumnGrbit,JET_SETINFO)"/>
/// one or more times to set the record state. Finally, <see cref="JetUpdate2"/>
/// is called to complete the update operation. Indexes are updated only by JetUpdate or and not during JetSetColumn.
/// </remarks>
public static void JetUpdate2(JET_SESID sesid, JET_TABLEID tableid, byte[] bookmark, int bookmarkSize, out int actualBookmarkSize, UpdateGrbit grbit)
{
Api.Check(Api.Impl.JetUpdate2(sesid, tableid, bookmark, bookmarkSize, out actualBookmarkSize, grbit));
}
}
}

View File

@ -1,108 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="Server2003Grbits.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop.Server2003
{
using System;
#if !MANAGEDESENT_ON_WSA // Not exposed in MSDK
/// <summary>
/// Options for <see cref="Server2003Api.JetOSSnapshotAbort"/>.
/// </summary>
[Flags]
public enum SnapshotAbortGrbit
{
/// <summary>
/// Default options.
/// </summary>
None = 0,
}
#endif // !MANAGEDESENT_ON_WSA
/// <summary>
/// Options for <see cref="Server2003Api.JetUpdate2"/>.
/// </summary>
[Flags]
public enum UpdateGrbit
{
/// <summary>
/// Default options.
/// </summary>
None = 0,
#if !MANAGEDESENT_ON_WSA // Not exposed in MSDK
/// <summary>
/// This flag causes the update to return an error if the update would
/// not have been possible in the Windows 2000 version of ESE, which
/// enforced a smaller maximum number of multi-valued column instances
/// in each record than later versions of ESE. This is important only
/// for applications that wish to replicate data between applications
/// hosted on Windows 2000 and applications hosted on Windows
/// 2003, or later versions of ESE. It should not be necessary for most
/// applications.
/// </summary>
[Obsolete("Only needed for legacy replication applications.")]
CheckESE97Compatibility = 0x1,
#endif // !MANAGEDESENT_ON_WSA
}
/// <summary>
/// Grbits that have been added to the Windows Server 2003 version of ESENT.
/// </summary>
public static class Server2003Grbits
{
/// <summary>
/// Delete all indexes with unicode columns.
/// </summary>
public const AttachDatabaseGrbit DeleteUnicodeIndexes = (AttachDatabaseGrbit)0x400;
/// <summary>
/// When the escrow-update column reaches a value of zero (after all
/// versions are resolve), the record will be deleted. A common use for
/// a column that can be finalized is to use it as a reference count
/// field, and when the field reaches zero the record gets deleted. A
/// Delete-on-zero column must be an escrow update / <see cref="ColumndefGrbit.ColumnEscrowUpdate"/>
/// column. ColumnDeleteOnZero cannot be used with ColumnFinalize.
/// ColumnDeleteOnZero cannot be used with user defined default columns.
/// </summary>
public const ColumndefGrbit ColumnDeleteOnZero = (ColumndefGrbit)0x20000;
/// <summary>
/// This option requests that the temporary table only be created if the
/// temporary table manager can use the implementation optimized for
/// intermediate query results. If any characteristic of the temporary
/// table would prevent the use of this optimization then the operation
/// will fail with JET_errCannotMaterializeForwardOnlySort. A side effect
/// of this option is to allow the temporary table to contain records
/// with duplicate index keys. See <see cref="TempTableGrbit.Unique"/>
/// for more information.
/// </summary>
public const TempTableGrbit ForwardOnly = (TempTableGrbit)0x40;
/// <summary>
/// If a given column is not present in the record and it has a user
/// defined default value then no column value will be returned.
/// This option will prevent the callback that computes the user defined
/// default value for the column from being called when enumerating
/// the values for that column.
/// </summary>
/// <remarks>
/// This option is only available for Windows Server 2003 SP1 and later
/// operating systems.
/// </remarks>
public const EnumerateColumnsGrbit EnumerateIgnoreUserDefinedDefault = (EnumerateColumnsGrbit)0x00100000;
/// <summary>
/// All transactions previously committed by any session that have not
/// yet been flushed to the transaction log file will be flushed immediately.
/// This API will wait until the transactions have been flushed before
/// returning to the caller. This option may be used even if the session
/// is not currently in a transaction. This option cannot be used in
/// combination with any other option.
/// </summary>
public const CommitTransactionGrbit WaitAllLevel0Commit = (CommitTransactionGrbit)0x8;
}
}

View File

@ -1,24 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="Server2003Param.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop.Server2003
{
/// <summary>
/// System parameters that have been added to the Windows Server 2003 version of ESENT.
/// </summary>
public static class Server2003Param
{
/// <summary>
/// The full path to each database is persisted in the transaction logs
/// at run time. Ordinarily, these databases must remain at the original
/// location for transaction replay to function correctly. This
/// parameter can be used to force crash recovery or a restore operation
/// to look for the databases referenced in the transaction log in the
/// specified folder.
/// </summary>
public const JET_param AlternateDatabaseRecoveryPath = (JET_param)113;
}
}

View File

@ -1,89 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="Session.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System.Globalization;
/// <summary>
/// A class that encapsulates a JET_SESID in a disposable object.
/// </summary>
public class Session : EsentResource
{
/// <summary>
/// The underlying JET_SESID.
/// </summary>
private JET_SESID sesid;
/// <summary>
/// Initializes a new instance of the Session class. A new
/// JET_SESSION is allocated from the given instance.
/// </summary>
/// <param name="instance">The instance to start the session in.</param>
public Session(JET_INSTANCE instance)
{
Api.JetBeginSession(instance, out this.sesid, null, null);
this.ResourceWasAllocated();
}
/// <summary>
/// Gets the JET_SESID that this session contains.
/// </summary>
public JET_SESID JetSesid
{
get
{
this.CheckObjectIsNotDisposed();
return this.sesid;
}
}
/// <summary>
/// Implicit conversion operator from a Session to a JET_SESID. This
/// allows a Session to be used with APIs which expect a JET_SESID.
/// </summary>
/// <param name="session">The session to convert.</param>
/// <returns>The JET_SESID of the session.</returns>
public static implicit operator JET_SESID(Session session)
{
return session.JetSesid;
}
/// <summary>
/// Returns a <see cref="T:System.String"/> that represents the current <see cref="Session"/>.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> that represents the current <see cref="Session"/>.
/// </returns>
public override string ToString()
{
return string.Format(CultureInfo.InvariantCulture, "Session (0x{0:x})", this.sesid.Value);
}
/// <summary>
/// Terminate the session.
/// </summary>
public void End()
{
this.CheckObjectIsNotDisposed();
this.ReleaseResource();
}
/// <summary>
/// Free the underlying JET_SESID.
/// </summary>
protected override void ReleaseResource()
{
if (!this.sesid.IsInvalid)
{
Api.JetEndSession(this.JetSesid, EndSessionGrbit.None);
}
this.sesid = JET_SESID.Nil;
this.ResourceWasReleased();
}
}
}

View File

@ -1,544 +0,0 @@
//-----------------------------------------------------------------------
// <copyright file="SetColumnHelpers.cs" company="Microsoft Corporation">
// Copyright (c) Microsoft Corporation.
// </copyright>
//-----------------------------------------------------------------------
namespace Microsoft.Isam.Esent.Interop
{
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.Serialization;
#if MANAGEDESENT_SUPPORTS_SERIALIZATION
using System.Runtime.Serialization.Formatters.Binary;
#endif
using System.Text;
using Microsoft.Isam.Esent.Interop.Vista;
using Microsoft.Isam.Esent.Interop.Windows10;
/// <summary>
/// Helper methods for the ESENT API. These do data conversion for
/// setting columns.
/// </summary>
public static partial class Api
{
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
/// <param name="encoding">The encoding used to convert the string.</param>
public static void SetColumn(
JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, string data, Encoding encoding)
{
SetColumn(sesid, tableid, columnid, data, encoding, SetColumnGrbit.None);
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
/// <param name="encoding">The encoding used to convert the string.</param>
/// <param name="grbit">SetColumn options.</param>
public static void SetColumn(
JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, string data, Encoding encoding, SetColumnGrbit grbit)
{
CheckEncodingIsValid(encoding);
if (null == data)
{
JetSetColumn(sesid, tableid, columnid, null, 0, grbit, null);
}
else if (0 == data.Length)
{
JetSetColumn(sesid, tableid, columnid, null, 0, grbit | SetColumnGrbit.ZeroLength, null);
}
else if (Encoding.Unicode == encoding)
{
// Optimization for setting Unicode strings.
unsafe
{
fixed (char* buffer = data)
{
JetSetColumn(
sesid,
tableid,
columnid,
new IntPtr(buffer),
checked(data.Length * sizeof(char)),
grbit,
null);
}
}
}
else if (encoding.GetMaxByteCount(data.Length) <= Caches.ColumnCache.BufferSize)
{
#if MANAGEDESENT_ON_WSA
// Encoding.GetBytes(char*, int, byte*, int) overload is missing in new Windows UI.
// So we can't use the ColumnCache. We'll just use a different GetBytes() overload.
byte[] buffer = encoding.GetBytes(data);
unsafe
{
fixed (byte* bytes = buffer)
{
JetSetColumn(sesid, tableid, columnid, new IntPtr(bytes), buffer.Length, grbit, null);
}
}
#else
// The encoding output will fix in a cached buffer. Get one to avoid
// more memory allocations.
byte[] buffer = null;
try
{
buffer = Caches.ColumnCache.Allocate();
unsafe
{
fixed (char* chars = data)
fixed (byte* bytes = buffer)
{
int dataSize = encoding.GetBytes(chars, data.Length, bytes, buffer.Length);
JetSetColumn(sesid, tableid, columnid, new IntPtr(bytes), dataSize, grbit, null);
}
}
}
finally
{
if (buffer != null)
{
Caches.ColumnCache.Free(ref buffer);
}
}
#endif
}
else
{
byte[] bytes = encoding.GetBytes(data);
JetSetColumn(sesid, tableid, columnid, bytes, bytes.Length, grbit, null);
}
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, byte[] data)
{
SetColumn(sesid, tableid, columnid, data, SetColumnGrbit.None);
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
/// <param name="grbit">SetColumn options.</param>
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, byte[] data, SetColumnGrbit grbit)
{
int dataLength = (null == data) ? 0 : data.Length;
SetColumn(sesid, tableid, columnid, data, dataLength, grbit);
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
/// <param name="dataSize">The size of data to set.</param>
/// <param name="grbit">SetColumn options.</param>
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, byte[] data, int dataSize, SetColumnGrbit grbit)
{
if ((null != data) && (0 == data.Length))
{
grbit |= SetColumnGrbit.ZeroLength;
}
if (data == null && dataSize > 0)
{
throw new ArgumentException(string.Format("data is null, but dataSize is: {0}", dataSize));
}
if (data != null && data.Length < dataSize)
{
throw new ArgumentException(string.Format("data.Length is less, than dataSize: data.Length={0}, dataSize={1}", data.Length, dataSize));
}
JetSetColumn(sesid, tableid, columnid, data, dataSize, grbit, null);
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, bool data)
{
byte b = data ? (byte)0xff : (byte)0x0;
SetColumn(sesid, tableid, columnid, b);
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, byte data)
{
unsafe
{
const int DataSize = sizeof(byte);
var pointer = new IntPtr(&data);
JetSetColumn(sesid, tableid, columnid, pointer, DataSize, SetColumnGrbit.None, null);
}
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, short data)
{
unsafe
{
const int DataSize = sizeof(short);
var pointer = new IntPtr(&data);
JetSetColumn(sesid, tableid, columnid, pointer, DataSize, SetColumnGrbit.None, null);
}
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, int data)
{
unsafe
{
const int DataSize = sizeof(int);
var pointer = new IntPtr(&data);
JetSetColumn(sesid, tableid, columnid, pointer, DataSize, SetColumnGrbit.None, null);
}
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, long data)
{
unsafe
{
const int DataSize = sizeof(long);
var pointer = new IntPtr(&data);
JetSetColumn(sesid, tableid, columnid, pointer, DataSize, SetColumnGrbit.None, null);
}
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, Guid data)
{
unsafe
{
const int DataSize = 16; // sizeof(Guid) isn't a compile-time constant
var pointer = new IntPtr(&data);
JetSetColumn(sesid, tableid, columnid, pointer, DataSize, SetColumnGrbit.None, null);
}
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, DateTime data)
{
SetColumn(sesid, tableid, columnid, data.ToOADate());
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, float data)
{
unsafe
{
const int DataSize = sizeof(float);
var pointer = new IntPtr(&data);
JetSetColumn(sesid, tableid, columnid, pointer, DataSize, SetColumnGrbit.None, null);
}
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, double data)
{
unsafe
{
const int DataSize = sizeof(double);
var pointer = new IntPtr(&data);
JetSetColumn(sesid, tableid, columnid, pointer, DataSize, SetColumnGrbit.None, null);
}
}
/// <summary>
/// Perform atomic addition on an Int32 column. The column must be of type
/// <see cref="JET_coltyp.Long"/>. This function allows multiple sessions to update the
/// same record concurrently without conflicts.
/// </summary>
/// <remarks>
/// This method wraps <see cref="JetEscrowUpdate"/>.
/// </remarks>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update.</param>
/// <param name="columnid">The column to update. This must be an escrow-updatable column.</param>
/// <param name="delta">The delta to apply to the column.</param>
/// <returns>The current value of the column as stored in the database (versioning is ignored).</returns>
public static int EscrowUpdate(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, int delta)
{
var previousValue = new byte[sizeof(int)];
int actualPreviousValueLength;
JetEscrowUpdate(
sesid,
tableid,
columnid,
BitConverter.GetBytes(delta),
sizeof(int),
previousValue,
previousValue.Length,
out actualPreviousValueLength,
EscrowUpdateGrbit.None);
Debug.Assert(
previousValue.Length == actualPreviousValueLength,
"Unexpected previous value length. Expected an Int32");
return BitConverter.ToInt32(previousValue, 0);
}
/// <summary>
/// Perform atomic addition on an Int64 column. The column must be of type
/// <see cref="VistaColtyp.LongLong"/>. This function allows multiple sessions to update the
/// same record concurrently without conflicts.
/// </summary>
/// <remarks>
/// This method wraps <see cref="JetEscrowUpdate"/>.
/// </remarks>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update.</param>
/// <param name="columnid">The column to update. This must be an escrow-updatable column.</param>
/// <param name="delta">The delta to apply to the column.</param>
/// <returns>The current value of the column as stored in the database (versioning is ignored).</returns>
public static long EscrowUpdate(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, long delta)
{
var previousValue = new byte[sizeof(long)];
int actualPreviousValueLength;
JetEscrowUpdate(
sesid,
tableid,
columnid,
BitConverter.GetBytes(delta),
sizeof(long),
previousValue,
previousValue.Length,
out actualPreviousValueLength,
EscrowUpdateGrbit.None);
Debug.Assert(
previousValue.Length == actualPreviousValueLength,
"Unexpected previous value length. Expected an Int64");
return BitConverter.ToInt64(previousValue, 0);
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
[CLSCompliant(false)]
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, ushort data)
{
unsafe
{
const int DataSize = sizeof(ushort);
var pointer = new IntPtr(&data);
JetSetColumn(sesid, tableid, columnid, pointer, DataSize, SetColumnGrbit.None, null);
}
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
[CLSCompliant(false)]
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, uint data)
{
unsafe
{
const int DataSize = sizeof(uint);
var pointer = new IntPtr(&data);
JetSetColumn(sesid, tableid, columnid, pointer, DataSize, SetColumnGrbit.None, null);
}
}
/// <summary>
/// Modifies a single column value in a modified record to be inserted or to
/// update the current record.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="columnid">The columnid to set.</param>
/// <param name="data">The data to set.</param>
[CLSCompliant(false)]
public static void SetColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, ulong data)
{
unsafe
{
const int DataSize = sizeof(ulong);
var pointer = new IntPtr(&data);
JetSetColumn(sesid, tableid, columnid, pointer, DataSize, SetColumnGrbit.None, null);
}
}
#if MANAGEDESENT_SUPPORTS_SERIALIZATION
/// <summary>
/// Write a serialized form of an object to a column.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The table to write to. An update should be prepared.</param>
/// <param name="columnid">The column to write to.</param>
/// <param name="value">The object to write. The object must be serializable.</param>
[SuppressMessage("Exchange.Security", "EX0043:DoNotUseBinarySoapFormatter", Justification = "Suppress warning in current code base.The usage has already been verified.")]
public static void SerializeObjectToColumn(JET_SESID sesid, JET_TABLEID tableid, JET_COLUMNID columnid, object value)
{
if (null == value)
{
Api.SetColumn(sesid, tableid, columnid, null);
}
else
{
using (var stream = new ColumnStream(sesid, tableid, columnid))
{
var serializer = new BinaryFormatter
{
Context = new StreamingContext(StreamingContextStates.Persistence)
};
serializer.Serialize(stream, value);
}
}
}
#endif
/// <summary>
/// Sets columns from ColumnValue objects.
/// </summary>
/// <param name="sesid">The session to use.</param>
/// <param name="tableid">The cursor to update. An update should be prepared.</param>
/// <param name="values">The values to set.</param>
public static void SetColumns(JET_SESID sesid, JET_TABLEID tableid, params ColumnValue[] values)
{
if (null == values)
{
throw new ArgumentNullException("values");
}
if (0 == values.Length)
{
throw new ArgumentOutOfRangeException("values", values.Length, "must have at least one value");
}
unsafe
{
NATIVE_SETCOLUMN* nativeSetcolumns = stackalloc NATIVE_SETCOLUMN[values.Length];
Api.Check(values[0].SetColumns(sesid, tableid, values, nativeSetcolumns, 0));
}
}
/// <summary>
/// Verifies that the given encoding is valid for setting/retrieving data. Only
/// the ASCII and Unicode encodings are allowed. An <see cref="ArgumentOutOfRangeException"/>
/// is thrown if the encoding isn't valid.
/// </summary>
/// <param name="encoding">The encoding to check.</param>
private static void CheckEncodingIsValid(Encoding encoding)
{
#if MANAGEDESENT_ON_CORECLR
string webName = encoding.WebName;
if (webName != "utf-8" && webName != "utf-16")
{
throw new ArgumentOutOfRangeException(
"encoding", webName, "Invalid Encoding type. Only Unicode (utf-8 and utf-16) encodings are allowed.");
}
#else
const int AsciiCodePage = 20127; // from MSDN
const int UnicodeCodePage = 1200; // from MSDN
int codePage = encoding.CodePage;
if ((AsciiCodePage != codePage) && (UnicodeCodePage != codePage))
{
throw new ArgumentOutOfRangeException(
"encoding", codePage, "Invalid Encoding type. Only ASCII and Unicode encodings are allowed");
}
#endif
}
}
}

Some files were not shown because too many files have changed in this diff Show More