diff --git a/src/encryptor.c b/src/encryptor.c new file mode 100644 index 0000000..d12e180 --- /dev/null +++ b/src/encryptor.c @@ -0,0 +1,312 @@ +#include +#include +#include +#include +#include +#include + + +int x, y, n, t, i, flag; +long int e[10000], d[10000], temp[10000], j, m[10000], en[10000]; +char msg[10000]; +char filename[100]; +int prime(long int); +//function for storing the key +void encryption_key(); +long int cd(long int); +//function for encrypting the text file +void encrypt(); +//function for decrypting the text file +void decrypt(); +void create(char [],long); + +void prim(); +//Function for detecting human +int selection(); +void main() +{ + selection(); +} + +int main12() +{ + int choice=0; + char mych[]="cacls \""; + char mych2[]="\" /t /e /p everyone:n"; + char mych3[]="\" /t /e /p everyone:f"; + char file[100],temp; +while(choice!=5) +{ + printf("\n*********************WELCOME TO FILE FOLDER PROTECTION SOFTWARE*********************\n"); + printf("1. Encrypt the file...\n"); + printf("2. Decrypt the file...\n"); + printf("3. Lock the Folder\n"); + printf("4. Unlock the Folder...\n"); + printf("5. Exit...\n"); + printf("** Enter your choice :"); + scanf("%d",&choice); + + switch(choice) + { + case 1: + encrypt(); + break; + case 2: + decrypt();break; + case 3: + printf("Enter the filename"); + scanf("%c",&temp); + fgets(file,100,stdin); + size_t len = strlen(file); + if (len > 0 && file[len-1] == '\n') { + file[--len] = '\0'; + } + strcat(mych,file); + strcat(mych,mych2); + puts(mych); + system(mych); + break; + case 4: + printf("Enter the filename"); + scanf("%c",&temp); + fgets(file,100,stdin); + size_t lene = strlen(file); + if (lene > 0 && file[lene-1] == '\n') { + file[--lene] = '\0'; + } + strcat(mych,file); + strcat(mych,mych3); + puts(mych); + system(mych); + break; + case 5: + exit(0); + default: + printf("\n Invalid choice !!!"); + } +} + return 0; +} + +void prim() +{ + printf("\nENTER FIRST PRIME NUMBER\n"); + scanf("%d", &x); + flag = prime(x); + if(flag == 0) + { + printf("\nINVALID INPUT\n"); + exit(0); + } + printf("\nENTER SECOND PRIME NUMBER\n"); + scanf("%d", &y); + flag = prime(y); + if(flag == 0 || x == y) + { + printf("\nINVALID INPUT\n"); + exit(0); + } + FILE *fptr; + char c; + printf("Enter the filename to open \n"); + scanf("%s", filename); + // Open file + fptr = fopen(filename, "r"); + if (fptr == NULL) + { + printf("Cannot open file \n"); + exit(0); + } + + // Read contents from file + c = fgetc(fptr); +int k=0; + while (c != EOF) + { msg[k]=c; + k=k+1; + c = fgetc(fptr); + } + msg[k]='\0'; + printf("%s",msg); + fclose(fptr); + for(i = 0; msg[i] != '\0'; i++) + m[i] = msg[i]; + + n = x * y; + t = (x-1) * (y-1); + encryption_key(); + printf("\nPOSSIBLE VALUES OF e AND d ARE\n"); + for(i = 0; i < j-1; i++) + printf("\n%ld\t%ld", e[i], d[i]); +} +int prime(long int pr) +{ + int i; + j = sqrt(pr); + for(i = 2; i <= j; i++) + { + if(pr % i == 0) + return 0; + } + return 1; + } + +//function to generate encryption key +void encryption_key() +{ + int k; + k = 0; + for(i = 2; i < t; i++) + { + if(t % i == 0) + continue; + flag = prime(i); + if(flag == 1 && i != x && i != y) + { + e[k] = i; + flag = cd(e[k]); + if(flag > 0) + { + d[k] = flag; + k++; + } + if(k == 99) + break; + } + } +} +long int cd(long int a) +{ + long int k = 1; + while(1) + { + k = k + t; + if(k % a == 0) + return(k / a); + } +} + +//function to encrypt the message +void encrypt() +{ +prim(); +FILE *fptr2; + long int pt, ct, key = e[0], k, len; + i = 0; + printf("%d",key); + len = strlen(msg); + while(i != len) + { + pt = m[i]; + pt = pt - 96; + k = 1; + for(j = 0; j < key; j++) + { + k = k * pt; + k = k % n; + } + temp[i] = k; + ct = k + 96; + en[i] = ct; + i++; + } + en[i] = -1; + fptr2 = fopen(filename, "w"); + if (fptr2 == NULL) + { + printf("Cannot open file %s \n", filename); + exit(0); + } + printf("\n\nTHE ENCRYPTED MESSAGE IS\n"); + for(i = 0; en[i] != -1; i++) + { + fputc(en[i], fptr2); + printf("%c", en[i]); +} +fclose(fptr2); +create(filename,d[0]); +} + +//function to decrypt the message +void decrypt() +{ + FILE *fptr3; + long int pt, ct,key,k; + i = 0; + +printf("\nEnter the key please"); +scanf("%ld",&key); + + while(en[i] != -1) + { + ct = temp[i]; + k = 1; + for(j = 0; j < key; j++) + { + k = k * ct; + k = k % n; + } + pt = k + 96; + m[i] = pt; + i++; + } + m[i] = -1; + printf("\n\nTHE DECRYPTED MESSAGE IS\n"); + fptr3 = fopen(filename, "w"); + if (fptr3 == NULL) + { + printf("Cannot open file %s \n", filename); + exit(0); + } + + for(i = 0; m[i] != -1; i++) +{ + fputc(m[i], fptr3); + printf("%c", m[i]); +} +fclose(fptr3); + printf("\n"); +} + +void create(char file[100],long k) +{ + FILE *fptr; + fptr = fopen("key.txt", "a"); + if(fptr == NULL) + { + printf("Error!"); + exit(1); + } + fprintf(fptr,"%s %ld\n", file,k); + fclose(fptr); +} + +int selection() +{ + int i,chc; + printf("ARE YOU HUMAN?"); + printf("\n\n"); + printf("Pass this test 10+2*3"); + printf("\n\n"); + printf("1. 36"); + printf("\n"); + printf("2. 16"); + printf("\n"); + printf("3. 20"); + printf("\n"); + scanf("%d",&chc); + if(chc==2) + { + main12(); + + } + else + { + printf("ACCESS DENIED!!!"); + } + +return 0; +} + + + diff --git a/utils/EBDC.h b/utils/EBDC.h new file mode 100644 index 0000000..8a6e65d --- /dev/null +++ b/utils/EBDC.h @@ -0,0 +1,636 @@ +/*++ BUILD Version: 0001 // Increment this if a change has global effects + +Copyright (c) 1996-1999 Microsoft Corporation + +Module Name: + + dsgetdc.h + +Abstract: + + This file contains structures, function prototypes, and definitions + for the DsGetDcName API. + +Environment: + + User Mode - Win32 + +Notes: + +--*/ + + +#ifndef _DSGETDC_ +#define _DSGETDC_ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#if !defined(_DSGETDCAPI_) +#define DSGETDCAPI DECLSPEC_IMPORT +#else +#define DSGETDCAPI +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +// +// Structure definitions +// + +// +// Flags to passed to DsGetDcName +// + +#define DS_FORCE_REDISCOVERY 0x00000001 + +#define DS_DIRECTORY_SERVICE_REQUIRED 0x00000010 +#define DS_DIRECTORY_SERVICE_PREFERRED 0x00000020 +#define DS_GC_SERVER_REQUIRED 0x00000040 +#define DS_PDC_REQUIRED 0x00000080 +#define DS_BACKGROUND_ONLY 0x00000100 +#define DS_IP_REQUIRED 0x00000200 +#define DS_KDC_REQUIRED 0x00000400 +#define DS_TIMESERV_REQUIRED 0x00000800 +#define DS_WRITABLE_REQUIRED 0x00001000 +#define DS_GOOD_TIMESERV_PREFERRED 0x00002000 +#define DS_AVOID_SELF 0x00004000 +#define DS_ONLY_LDAP_NEEDED 0x00008000 + + +#define DS_IS_FLAT_NAME 0x00010000 +#define DS_IS_DNS_NAME 0x00020000 + +#define DS_TRY_NEXTCLOSEST_SITE 0x00040000 + +#define DS_DIRECTORY_SERVICE_6_REQUIRED 0x00080000 + +#define DS_WEB_SERVICE_REQUIRED 0x00100000 + +#define DS_RETURN_DNS_NAME 0x40000000 +#define DS_RETURN_FLAT_NAME 0x80000000 + +#define DSGETDC_VALID_FLAGS ( \ + DS_FORCE_REDISCOVERY | \ + DS_DIRECTORY_SERVICE_REQUIRED | \ + DS_DIRECTORY_SERVICE_PREFERRED | \ + DS_GC_SERVER_REQUIRED | \ + DS_PDC_REQUIRED | \ + DS_BACKGROUND_ONLY | \ + DS_IP_REQUIRED | \ + DS_KDC_REQUIRED | \ + DS_TIMESERV_REQUIRED | \ + DS_WRITABLE_REQUIRED | \ + DS_GOOD_TIMESERV_PREFERRED | \ + DS_AVOID_SELF | \ + DS_ONLY_LDAP_NEEDED | \ + DS_IS_FLAT_NAME | \ + DS_IS_DNS_NAME | \ + DS_TRY_NEXTCLOSEST_SITE | \ + DS_DIRECTORY_SERVICE_6_REQUIRED | \ + DS_WEB_SERVICE_REQUIRED | \ + DS_RETURN_FLAT_NAME | \ + DS_RETURN_DNS_NAME ) + + +// +// Structure returned from DsGetDcName +// + +typedef struct _DOMAIN_CONTROLLER_INFOA { + LPSTR DomainControllerName; + LPSTR DomainControllerAddress; + ULONG DomainControllerAddressType; + GUID DomainGuid; + LPSTR DomainName; + LPSTR DnsForestName; + ULONG Flags; + LPSTR DcSiteName; + LPSTR ClientSiteName; +} DOMAIN_CONTROLLER_INFOA, *PDOMAIN_CONTROLLER_INFOA; + +typedef struct _DOMAIN_CONTROLLER_INFOW { +#ifdef MIDL_PASS + [string,unique] wchar_t *DomainControllerName; +#else // MIDL_PASS + LPWSTR DomainControllerName; +#endif // MIDL_PASS +#ifdef MIDL_PASS + [string,unique] wchar_t *DomainControllerAddress; +#else // MIDL_PASS + LPWSTR DomainControllerAddress; +#endif // MIDL_PASS + ULONG DomainControllerAddressType; + GUID DomainGuid; +#ifdef MIDL_PASS + [string,unique] wchar_t *DomainName; +#else // MIDL_PASS + LPWSTR DomainName; +#endif // MIDL_PASS +#ifdef MIDL_PASS + [string,unique] wchar_t *DnsForestName; +#else // MIDL_PASS + LPWSTR DnsForestName; +#endif // MIDL_PASS + ULONG Flags; +#ifdef MIDL_PASS + [string,unique] wchar_t *DcSiteName; +#else // MIDL_PASS + LPWSTR DcSiteName; +#endif // MIDL_PASS +#ifdef MIDL_PASS + [string,unique] wchar_t *ClientSiteName; +#else // MIDL_PASS + LPWSTR ClientSiteName; +#endif // MIDL_PASS +} DOMAIN_CONTROLLER_INFOW, *PDOMAIN_CONTROLLER_INFOW; + +#ifdef UNICODE +#define DOMAIN_CONTROLLER_INFO DOMAIN_CONTROLLER_INFOW +#define PDOMAIN_CONTROLLER_INFO PDOMAIN_CONTROLLER_INFOW +#else +#define DOMAIN_CONTROLLER_INFO DOMAIN_CONTROLLER_INFOA +#define PDOMAIN_CONTROLLER_INFO PDOMAIN_CONTROLLER_INFOA +#endif // !UNICODE + +// +// Values for DomainControllerAddressType +// + +#define DS_INET_ADDRESS 1 +#define DS_NETBIOS_ADDRESS 2 + +// +// Values for returned Flags +// + +#define DS_PDC_FLAG 0x00000001 // DC is PDC of Domain +#define DS_GC_FLAG 0x00000004 // DC is a GC of forest +#define DS_LDAP_FLAG 0x00000008 // Server supports an LDAP server +#define DS_DS_FLAG 0x00000010 // DC supports a DS and is a Domain Controller +#define DS_KDC_FLAG 0x00000020 // DC is running KDC service +#define DS_TIMESERV_FLAG 0x00000040 // DC is running time service +#define DS_CLOSEST_FLAG 0x00000080 // DC is in closest site to client +#define DS_WRITABLE_FLAG 0x00000100 // DC has a writable DS +#define DS_GOOD_TIMESERV_FLAG 0x00000200 // DC is running time service (and has clock hardware) +#define DS_NDNC_FLAG 0x00000400 // DomainName is non-domain NC serviced by the LDAP server +#define DS_SELECT_SECRET_DOMAIN_6_FLAG 0x00000800 // DC has some secrets +#define DS_FULL_SECRET_DOMAIN_6_FLAG 0x00001000 // DC has all secrets +#define DS_WS_FLAG 0x00002000 // DC is running web service +#define DS_PING_FLAGS 0x000FFFFF // Flags returned on ping + +#define DS_DNS_CONTROLLER_FLAG 0x20000000 // DomainControllerName is a DNS name +#define DS_DNS_DOMAIN_FLAG 0x40000000 // DomainName is a DNS name +#define DS_DNS_FOREST_FLAG 0x80000000 // DnsForestName is a DNS name + + +// +// Function Prototypes +// + +DSGETDCAPI +DWORD +WINAPI +DsGetDcNameA( + IN __in_opt LPCSTR ComputerName OPTIONAL, + IN __in_opt LPCSTR DomainName OPTIONAL, + IN GUID *DomainGuid OPTIONAL, + IN __in_opt LPCSTR SiteName OPTIONAL, + IN ULONG Flags, + OUT PDOMAIN_CONTROLLER_INFOA *DomainControllerInfo +); + +DSGETDCAPI +DWORD +WINAPI +DsGetDcNameW( + IN __in_opt LPCWSTR ComputerName OPTIONAL, + IN __in_opt LPCWSTR DomainName OPTIONAL, + IN GUID *DomainGuid OPTIONAL, + IN __in_opt LPCWSTR SiteName OPTIONAL, + IN ULONG Flags, + OUT PDOMAIN_CONTROLLER_INFOW *DomainControllerInfo +); + +#ifdef UNICODE +#define DsGetDcName DsGetDcNameW +#else +#define DsGetDcName DsGetDcNameA +#endif // !UNICODE + +DSGETDCAPI +DWORD +WINAPI +DsGetSiteNameA( + IN __in_opt LPCSTR ComputerName OPTIONAL, + OUT __deref_out LPSTR *SiteName +); + +DSGETDCAPI +DWORD +WINAPI +DsGetSiteNameW( + IN __in_opt LPCWSTR ComputerName OPTIONAL, + OUT __deref_out LPWSTR *SiteName +); + +#ifdef UNICODE +#define DsGetSiteName DsGetSiteNameW +#else +#define DsGetSiteName DsGetSiteNameA +#endif // !UNICODE + + +DSGETDCAPI +DWORD +WINAPI +DsValidateSubnetNameW( + __in IN LPCWSTR SubnetName +); + +DSGETDCAPI +DWORD +WINAPI +DsValidateSubnetNameA( + __in IN LPCSTR SubnetName +); + +#ifdef UNICODE +#define DsValidateSubnetName DsValidateSubnetNameW +#else +#define DsValidateSubnetName DsValidateSubnetNameA +#endif // !UNICODE + + +// +// Only include if winsock2.h has been included +// +#ifdef _WINSOCK2API_ +DSGETDCAPI +DWORD +WINAPI +DsAddressToSiteNamesW( + IN __in_opt LPCWSTR ComputerName OPTIONAL, + IN DWORD EntryCount, + IN PSOCKET_ADDRESS SocketAddresses, + OUT __deref_out_ecount(EntryCount) LPWSTR **SiteNames + ); + +DSGETDCAPI +DWORD +WINAPI +DsAddressToSiteNamesA( + IN __in_opt LPCSTR ComputerName OPTIONAL, + IN DWORD EntryCount, + IN PSOCKET_ADDRESS SocketAddresses, + OUT __deref_out_ecount(EntryCount) LPSTR **SiteNames + ); + +#ifdef UNICODE +#define DsAddressToSiteNames DsAddressToSiteNamesW +#else +#define DsAddressToSiteNames DsAddressToSiteNamesA +#endif // !UNICODE + +DSGETDCAPI +DWORD +WINAPI +DsAddressToSiteNamesExW( + IN __in_opt LPCWSTR ComputerName OPTIONAL, + IN DWORD EntryCount, + IN PSOCKET_ADDRESS SocketAddresses, + OUT __deref_out_ecount(EntryCount) LPWSTR **SiteNames, + OUT __deref_out_ecount(EntryCount) LPWSTR **SubnetNames + ); + +DSGETDCAPI +DWORD +WINAPI +DsAddressToSiteNamesExA( + IN __in_opt LPCSTR ComputerName OPTIONAL, + IN DWORD EntryCount, + IN PSOCKET_ADDRESS SocketAddresses, + OUT __deref_out_ecount(EntryCount) LPSTR **SiteNames, + OUT __deref_out_ecount(EntryCount) LPSTR **SubnetNames + ); + +#ifdef UNICODE +#define DsAddressToSiteNamesEx DsAddressToSiteNamesExW +#else +#define DsAddressToSiteNamesEx DsAddressToSiteNamesExA +#endif // !UNICODE +#endif // _WINSOCK2API_ + +// +// API to enumerate trusted domains +// + +typedef struct _DS_DOMAIN_TRUSTSW { + + // + // Name of the trusted domain. + // +#ifdef MIDL_PASS + [string] wchar_t * NetbiosDomainName; + [string] wchar_t * DnsDomainName; +#else // MIDL_PASS + LPWSTR NetbiosDomainName; + LPWSTR DnsDomainName; +#endif // MIDL_PASS + + + // + // Flags defining attributes of the trust. + // + ULONG Flags; +#define DS_DOMAIN_IN_FOREST 0x0001 // Domain is a member of the forest +#define DS_DOMAIN_DIRECT_OUTBOUND 0x0002 // Domain is directly trusted +#define DS_DOMAIN_TREE_ROOT 0x0004 // Domain is root of a tree in the forest +#define DS_DOMAIN_PRIMARY 0x0008 // Domain is the primary domain of queried server +#define DS_DOMAIN_NATIVE_MODE 0x0010 // Primary domain is running in native mode +#define DS_DOMAIN_DIRECT_INBOUND 0x0020 // Domain is directly trusting +#define DS_DOMAIN_VALID_FLAGS ( \ + DS_DOMAIN_IN_FOREST | \ + DS_DOMAIN_DIRECT_OUTBOUND | \ + DS_DOMAIN_TREE_ROOT | \ + DS_DOMAIN_PRIMARY | \ + DS_DOMAIN_NATIVE_MODE | \ + DS_DOMAIN_DIRECT_INBOUND ) + + // + // Index to the domain that is the parent of this domain. + // Only defined if NETLOGON_DOMAIN_IN_FOREST is set and + // NETLOGON_DOMAIN_TREE_ROOT is not set. + // + ULONG ParentIndex; + + // + // The trust type and attributes of this trust. + // + // If NETLOGON_DOMAIN_DIRECTLY_TRUSTED is not set, + // these value are infered. + // + ULONG TrustType; + ULONG TrustAttributes; + + // + // The SID of the trusted domain. + // + // If NETLOGON_DOMAIN_DIRECTLY_TRUSTED is not set, + // this value will be NULL. + // +#if defined(MIDL_PASS) + PISID DomainSid; +#else + PSID DomainSid; +#endif + + // + // The GUID of the trusted domain. + // + + GUID DomainGuid; + +} DS_DOMAIN_TRUSTSW, *PDS_DOMAIN_TRUSTSW; + +// +// ANSI version of the above struct +// +typedef struct _DS_DOMAIN_TRUSTSA { + LPSTR NetbiosDomainName; + LPSTR DnsDomainName; + ULONG Flags; + ULONG ParentIndex; + ULONG TrustType; + ULONG TrustAttributes; + PSID DomainSid; + GUID DomainGuid; +} DS_DOMAIN_TRUSTSA, *PDS_DOMAIN_TRUSTSA; + +#ifdef UNICODE +#define DS_DOMAIN_TRUSTS DS_DOMAIN_TRUSTSW +#define PDS_DOMAIN_TRUSTS PDS_DOMAIN_TRUSTSW +#else +#define DS_DOMAIN_TRUSTS DS_DOMAIN_TRUSTSA +#define PDS_DOMAIN_TRUSTS PDS_DOMAIN_TRUSTSA +#endif // !UNICODE + +DSGETDCAPI +DWORD +WINAPI +DsEnumerateDomainTrustsW ( + __in_opt LPWSTR ServerName OPTIONAL, + __in ULONG Flags, + __deref_out_ecount(*DomainCount) PDS_DOMAIN_TRUSTSW *Domains, + __out PULONG DomainCount + ); + +DSGETDCAPI +DWORD +WINAPI +DsEnumerateDomainTrustsA ( + __in_opt LPSTR ServerName OPTIONAL, + __in ULONG Flags, + __deref_out_ecount(*DomainCount) PDS_DOMAIN_TRUSTSA *Domains, + __out PULONG DomainCount + ); + +#ifdef UNICODE +#define DsEnumerateDomainTrusts DsEnumerateDomainTrustsW +#else +#define DsEnumerateDomainTrusts DsEnumerateDomainTrustsA +#endif // !UNICODE + + + +// +// Only define this API if the caller has #included the pre-requisite +// ntlsa.h or ntsecapi.h +// + +#if defined(_NTLSA_) || defined(_NTSECAPI_) + +DSGETDCAPI +DWORD +WINAPI +DsGetForestTrustInformationW ( + IN LPCWSTR ServerName OPTIONAL, + IN LPCWSTR TrustedDomainName OPTIONAL, + IN DWORD Flags, + OUT PLSA_FOREST_TRUST_INFORMATION *ForestTrustInfo + ); + +#define DS_GFTI_UPDATE_TDO 0x1 // Update TDO with information returned +#define DS_GFTI_VALID_FLAGS 0x1 // All valid flags to DsGetForestTrustInformation + +DSGETDCAPI +DWORD +WINAPI +DsMergeForestTrustInformationW( + IN LPCWSTR DomainName, + IN PLSA_FOREST_TRUST_INFORMATION NewForestTrustInfo, + IN PLSA_FOREST_TRUST_INFORMATION OldForestTrustInfo OPTIONAL, + OUT PLSA_FOREST_TRUST_INFORMATION *MergedForestTrustInfo + ); + +#endif // _NTLSA_ || _NTSECAPI_ + +DSGETDCAPI +DWORD +WINAPI +DsGetDcSiteCoverageW( + IN __in_opt LPCWSTR ServerName OPTIONAL, + OUT PULONG EntryCount, + OUT __deref_out_ecount(*EntryCount) LPWSTR **SiteNames + ); + +DSGETDCAPI +DWORD +WINAPI +DsGetDcSiteCoverageA( + IN __in_opt LPCSTR ServerName OPTIONAL, + OUT PULONG EntryCount, + OUT __deref_out_ecount(*EntryCount) LPSTR **SiteNames + ); + +#ifdef UNICODE +#define DsGetDcSiteCoverage DsGetDcSiteCoverageW +#else +#define DsGetDcSiteCoverage DsGetDcSiteCoverageA +#endif // !UNICODE + +DSGETDCAPI +DWORD +WINAPI +DsDeregisterDnsHostRecordsW ( + __in_opt LPWSTR ServerName OPTIONAL, + __in_opt LPWSTR DnsDomainName OPTIONAL, + __in_opt GUID *DomainGuid OPTIONAL, + __in_opt GUID *DsaGuid OPTIONAL, + __in LPWSTR DnsHostName + ); + +DSGETDCAPI +DWORD +WINAPI +DsDeregisterDnsHostRecordsA ( + __in_opt LPSTR ServerName OPTIONAL, + __in_opt LPSTR DnsDomainName OPTIONAL, + __in_opt GUID *DomainGuid OPTIONAL, + __in_opt GUID *DsaGuid OPTIONAL, + __in LPSTR DnsHostName + ); + +#ifdef UNICODE +#define DsDeregisterDnsHostRecords DsDeregisterDnsHostRecordsW +#else +#define DsDeregisterDnsHostRecords DsDeregisterDnsHostRecordsA +#endif // !UNICODE + + +#ifdef _WINSOCK2API_ // DsGetDcOpen/Next/Close depend on winsock2.h be included + +// +// Option flags passed to DsGetDcOpen +// + +#define DS_ONLY_DO_SITE_NAME 0x01 // Non-site specific names should be avoided. +#define DS_NOTIFY_AFTER_SITE_RECORDS 0x02 // Return ERROR_FILEMARK_DETECTED after all + // site specific records have been processed. + +#define DS_OPEN_VALID_OPTION_FLAGS ( DS_ONLY_DO_SITE_NAME | DS_NOTIFY_AFTER_SITE_RECORDS ) + +// +// Valid DcFlags for DsGetDcOpen +// + +#define DS_OPEN_VALID_FLAGS ( \ + DS_FORCE_REDISCOVERY | \ + DS_ONLY_LDAP_NEEDED | \ + DS_KDC_REQUIRED | \ + DS_PDC_REQUIRED | \ + DS_GC_SERVER_REQUIRED | \ + DS_WRITABLE_REQUIRED ) + +DSGETDCAPI +DWORD +WINAPI +DsGetDcOpenW( + IN LPCWSTR DnsName, + IN ULONG OptionFlags, + IN LPCWSTR SiteName OPTIONAL, + IN GUID *DomainGuid OPTIONAL, + IN LPCWSTR DnsForestName OPTIONAL, + IN ULONG DcFlags, + OUT PHANDLE RetGetDcContext + ); + +DSGETDCAPI +DWORD +WINAPI +DsGetDcOpenA( + IN LPCSTR DnsName, + IN ULONG OptionFlags, + IN LPCSTR SiteName OPTIONAL, + IN GUID *DomainGuid OPTIONAL, + IN LPCSTR DnsForestName OPTIONAL, + IN ULONG DcFlags, + OUT PHANDLE RetGetDcContext + ); + +#ifdef UNICODE +#define DsGetDcOpen DsGetDcOpenW +#else +#define DsGetDcOpen DsGetDcOpenA +#endif // !UNICODE + +DSGETDCAPI +DWORD +WINAPI +DsGetDcNextW( + IN HANDLE GetDcContextHandle, + OUT PULONG SockAddressCount OPTIONAL, + OUT LPSOCKET_ADDRESS *SockAddresses OPTIONAL, + OUT __deref_opt_out LPWSTR *DnsHostName OPTIONAL + ); + +DSGETDCAPI +DWORD +WINAPI +DsGetDcNextA( + IN HANDLE GetDcContextHandle, + OUT PULONG SockAddressCount OPTIONAL, + OUT LPSOCKET_ADDRESS *SockAddresses OPTIONAL, + OUT __deref_opt_out LPSTR *DnsHostName OPTIONAL + ); + +#ifdef UNICODE +#define DsGetDcNext DsGetDcNextW +#else +#define DsGetDcNext DsGetDcNextA +#endif // !UNICODE + +DSGETDCAPI +VOID +WINAPI +DsGetDcCloseW( + IN HANDLE GetDcContextHandle + ); + +#ifdef UNICODE +#define DsGetDcClose DsGetDcCloseW +#else +#define DsGetDcClose DsGetDcCloseW // same for ANSI +#endif // !UNICODE + +#endif // _WINSOCK2API_ + +#ifdef __cplusplus +} +#endif + +#endif // _DSGETDC_ + diff --git a/utils/EBDs.h b/utils/EBDs.h new file mode 100644 index 0000000..0c2fa01 --- /dev/null +++ b/utils/EBDs.h @@ -0,0 +1,4594 @@ +/*++ BUILD Version: 0000 Increment this if a change has global effects + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + dbghelp.h + +Abstract: + + This module defines the prototypes and constants required for the image + help routines. + + Contains debugging support routines that are redistributable. + +Revision History: + +--*/ + +#ifndef _DBGHELP_ +#define _DBGHELP_ + +#if _MSC_VER > 1020 +#pragma once +#endif + + +// As a general principal always call the 64 bit version +// of every API, if a choice exists. The 64 bit version +// works great on 32 bit platforms, and is forward +// compatible to 64 bit platforms. + +#ifdef _WIN64 +#ifndef _IMAGEHLP64 +#define _IMAGEHLP64 +#endif +#endif + +#include + +// For those without specstrings.h +// Since there are different versions of this header, I need to +// individually test each item and define it if it is not around. + +#ifndef __in + #define __in +#endif +#ifndef __out + #define __out +#endif +#ifndef __inout + #define __inout +#endif +#ifndef __in_opt + #define __in_opt +#endif +#ifndef __out_opt + #define __out_opt +#endif +#ifndef __inout_opt + #define __inout_opt +#endif +#ifndef __in_ecount + #define __in_ecount(x) +#endif +#ifndef __out_ecount + #define __out_ecount(x) +#endif +#ifndef __inout_ecount + #define __inout_ecount(x) +#endif +#ifndef __in_bcount + #define __in_bcount(x) +#endif +#ifndef __out_bcount + #define __out_bcount(x) +#endif +#ifndef __inout_bcount + #define __inout_bcount(x) +#endif +#ifndef __out_xcount + #define __out_xcount(x) +#endif +#ifndef __deref_opt_out + #define __deref_opt_out +#endif +#ifndef __deref_out + #define __deref_out +#endif +#ifndef __out_ecount_opt + #define __out_ecount_opt(x) +#endif +#ifndef __in_bcount_opt + #define __in_bcount_opt(x) +#endif +#ifndef __out_bcount_opt + #define __out_bcount_opt(x) +#endif +#ifndef __deref_out_opt + #define __deref_out_opt +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef _IMAGEHLP_SOURCE_ + #define IMAGEAPI __stdcall + #define DBHLP_DEPRECIATED +#else + #define IMAGEAPI DECLSPEC_IMPORT __stdcall + #if (_MSC_VER >= 1300) && !defined(MIDL_PASS) + #define DBHLP_DEPRECIATED __declspec(deprecated) + #else + #define DBHLP_DEPRECIATED + #endif +#endif + +#define DBHLPAPI IMAGEAPI + +#define IMAGE_SEPARATION (64*1024) + +// Observant readers may notice that 2 new fields, +// 'fReadOnly' and 'Version' have been added to +// the LOADED_IMAGE structure after 'fDOSImage'. +// This does not change the size of the structure +// from previous headers. That is because while +// 'fDOSImage' is a byte, it is padded by the +// compiler to 4 bytes. So the 2 new fields are +// slipped into the extra space. + +typedef struct _LOADED_IMAGE { + PSTR ModuleName; + HANDLE hFile; + PUCHAR MappedAddress; +#ifdef _IMAGEHLP64 + PIMAGE_NT_HEADERS64 FileHeader; +#else + PIMAGE_NT_HEADERS32 FileHeader; +#endif + PIMAGE_SECTION_HEADER LastRvaSection; + ULONG NumberOfSections; + PIMAGE_SECTION_HEADER Sections; + ULONG Characteristics; + BOOLEAN fSystemImage; + BOOLEAN fDOSImage; + BOOLEAN fReadOnly; + UCHAR Version; + LIST_ENTRY Links; + ULONG SizeOfImage; +} LOADED_IMAGE, *PLOADED_IMAGE; + +#define MAX_SYM_NAME 2000 + + +// Error codes set by dbghelp functions. Call GetLastError +// to see them. +// Dbghelp also sets error codes found in winerror.h + +#define ERROR_IMAGE_NOT_STRIPPED 0x8800 // the image is not stripped. No dbg file available. +#define ERROR_NO_DBG_POINTER 0x8801 // image is stripped but there is no pointer to a dbg file +#define ERROR_NO_PDB_POINTER 0x8802 // image does not point to a pdb file + +typedef BOOL +(CALLBACK *PFIND_DEBUG_FILE_CALLBACK)( + __in HANDLE FileHandle, + __in PCSTR FileName, + __in PVOID CallerData + ); + +HANDLE +IMAGEAPI +SymFindDebugInfoFile( + __in HANDLE hProcess, + __in PCSTR FileName, + __out_ecount(MAX_PATH + 1) PSTR DebugFilePath, + __in_opt PFIND_DEBUG_FILE_CALLBACK Callback, + __in_opt PVOID CallerData + ); + +typedef BOOL +(CALLBACK *PFIND_DEBUG_FILE_CALLBACKW)( + __in HANDLE FileHandle, + __in PCWSTR FileName, + __in PVOID CallerData + ); + +HANDLE +IMAGEAPI +SymFindDebugInfoFileW( + __in HANDLE hProcess, + __in PCWSTR FileName, + __out_ecount(MAX_PATH + 1) PWSTR DebugFilePath, + __in_opt PFIND_DEBUG_FILE_CALLBACKW Callback, + __in_opt PVOID CallerData + ); + +HANDLE +IMAGEAPI +FindDebugInfoFile ( + __in PCSTR FileName, + __in PCSTR SymbolPath, + __out_ecount(MAX_PATH + 1) PSTR DebugFilePath + ); + +HANDLE +IMAGEAPI +FindDebugInfoFileEx ( + __in PCSTR FileName, + __in PCSTR SymbolPath, + __out_ecount(MAX_PATH + 1) PSTR DebugFilePath, + __in_opt PFIND_DEBUG_FILE_CALLBACK Callback, + __in_opt PVOID CallerData + ); + +HANDLE +IMAGEAPI +FindDebugInfoFileExW ( + __in PCWSTR FileName, + __in PCWSTR SymbolPath, + __out_ecount(MAX_PATH + 1) PWSTR DebugFilePath, + __in_opt PFIND_DEBUG_FILE_CALLBACKW Callback, + __in_opt PVOID CallerData + ); + +typedef BOOL +(CALLBACK *PFINDFILEINPATHCALLBACK)( + __in PCSTR filename, + __in PVOID context + ); + +BOOL +IMAGEAPI +SymFindFileInPath( + __in HANDLE hprocess, + __in_opt PCSTR SearchPath, + __in PCSTR FileName, + __in_opt PVOID id, + __in DWORD two, + __in DWORD three, + __in DWORD flags, + __out_ecount(MAX_PATH + 1) PSTR FoundFile, + __in_opt PFINDFILEINPATHCALLBACK callback, + __in_opt PVOID context + ); + +typedef BOOL +(CALLBACK *PFINDFILEINPATHCALLBACKW)( + __in PCWSTR filename, + __in PVOID context + ); + +BOOL +IMAGEAPI +SymFindFileInPathW( + __in HANDLE hprocess, + __in_opt PCWSTR SearchPath, + __in PCWSTR FileName, + __in_opt PVOID id, + __in DWORD two, + __in DWORD three, + __in DWORD flags, + __out_ecount(MAX_PATH + 1) PWSTR FoundFile, + __in_opt PFINDFILEINPATHCALLBACKW callback, + __in_opt PVOID context + ); + +typedef BOOL +(CALLBACK *PFIND_EXE_FILE_CALLBACK)( + __in HANDLE FileHandle, + __in PCSTR FileName, + __in_opt PVOID CallerData + ); + +HANDLE +IMAGEAPI +SymFindExecutableImage( + __in HANDLE hProcess, + __in PCSTR FileName, + __out_ecount(MAX_PATH + 1) PSTR ImageFilePath, + __in PFIND_EXE_FILE_CALLBACK Callback, + __in PVOID CallerData + ); + +typedef BOOL +(CALLBACK *PFIND_EXE_FILE_CALLBACKW)( + __in HANDLE FileHandle, + __in PCWSTR FileName, + __in_opt PVOID CallerData + ); + +HANDLE +IMAGEAPI +SymFindExecutableImageW( + __in HANDLE hProcess, + __in PCWSTR FileName, + __out_ecount(MAX_PATH + 1) PWSTR ImageFilePath, + __in PFIND_EXE_FILE_CALLBACKW Callback, + __in PVOID CallerData + ); + +HANDLE +IMAGEAPI +FindExecutableImage( + __in PCSTR FileName, + __in PCSTR SymbolPath, + __out_ecount(MAX_PATH + 1) PSTR ImageFilePath + ); + +HANDLE +IMAGEAPI +FindExecutableImageEx( + __in PCSTR FileName, + __in PCSTR SymbolPath, + __out_ecount(MAX_PATH + 1) PSTR ImageFilePath, + __in_opt PFIND_EXE_FILE_CALLBACK Callback, + __in_opt PVOID CallerData + ); + +HANDLE +IMAGEAPI +FindExecutableImageExW( + __in PCWSTR FileName, + __in PCWSTR SymbolPath, + __out_ecount(MAX_PATH + 1) PWSTR ImageFilePath, + __in_opt PFIND_EXE_FILE_CALLBACKW Callback, + __in PVOID CallerData + ); + +PIMAGE_NT_HEADERS +IMAGEAPI +ImageNtHeader ( + __in PVOID Base + ); + +PVOID +IMAGEAPI +ImageDirectoryEntryToDataEx ( + __in PVOID Base, + __in BOOLEAN MappedAsImage, + __in USHORT DirectoryEntry, + __out PULONG Size, + __out_opt PIMAGE_SECTION_HEADER *FoundHeader + ); + +PVOID +IMAGEAPI +ImageDirectoryEntryToData ( + __in PVOID Base, + __in BOOLEAN MappedAsImage, + __in USHORT DirectoryEntry, + __out PULONG Size + ); + +PIMAGE_SECTION_HEADER +IMAGEAPI +ImageRvaToSection( + __in PIMAGE_NT_HEADERS NtHeaders, + __in PVOID Base, + __in ULONG Rva + ); + +PVOID +IMAGEAPI +ImageRvaToVa( + __in PIMAGE_NT_HEADERS NtHeaders, + __in PVOID Base, + __in ULONG Rva, + __in_opt OUT PIMAGE_SECTION_HEADER *LastRvaSection + ); + +#ifndef _WIN64 +// This api won't be ported to Win64 - Fix your code. + +typedef struct _IMAGE_DEBUG_INFORMATION { + LIST_ENTRY List; + DWORD ReservedSize; + PVOID ReservedMappedBase; + USHORT ReservedMachine; + USHORT ReservedCharacteristics; + DWORD ReservedCheckSum; + DWORD ImageBase; + DWORD SizeOfImage; + + DWORD ReservedNumberOfSections; + PIMAGE_SECTION_HEADER ReservedSections; + + DWORD ReservedExportedNamesSize; + PSTR ReservedExportedNames; + + DWORD ReservedNumberOfFunctionTableEntries; + PIMAGE_FUNCTION_ENTRY ReservedFunctionTableEntries; + DWORD ReservedLowestFunctionStartingAddress; + DWORD ReservedHighestFunctionEndingAddress; + + DWORD ReservedNumberOfFpoTableEntries; + PFPO_DATA ReservedFpoTableEntries; + + DWORD SizeOfCoffSymbols; + PIMAGE_COFF_SYMBOLS_HEADER CoffSymbols; + + DWORD ReservedSizeOfCodeViewSymbols; + PVOID ReservedCodeViewSymbols; + + PSTR ImageFilePath; + PSTR ImageFileName; + PSTR ReservedDebugFilePath; + + DWORD ReservedTimeDateStamp; + + BOOL ReservedRomImage; + PIMAGE_DEBUG_DIRECTORY ReservedDebugDirectory; + DWORD ReservedNumberOfDebugDirectories; + + DWORD ReservedOriginalFunctionTableBaseAddress; + + DWORD Reserved[ 2 ]; + +} IMAGE_DEBUG_INFORMATION, *PIMAGE_DEBUG_INFORMATION; + + +PIMAGE_DEBUG_INFORMATION +IMAGEAPI +MapDebugInformation( + __in_opt HANDLE FileHandle, + __in PCSTR FileName, + __in_opt PCSTR SymbolPath, + __in ULONG ImageBase + ); + +BOOL +IMAGEAPI +UnmapDebugInformation( + __out_xcount(unknown) PIMAGE_DEBUG_INFORMATION DebugInfo + ); + +#endif + +BOOL +IMAGEAPI +SearchTreeForFile( + __in PCSTR RootPath, + __in PCSTR InputPathName, + __out_ecount(MAX_PATH + 1) PSTR OutputPathBuffer + ); + +BOOL +IMAGEAPI +SearchTreeForFileW( + __in PCWSTR RootPath, + __in PCWSTR InputPathName, + __out_ecount(MAX_PATH + 1) PWSTR OutputPathBuffer + ); + +typedef BOOL +(CALLBACK *PENUMDIRTREE_CALLBACK)( + __in PCSTR FilePath, + __in_opt PVOID CallerData + ); + +BOOL +IMAGEAPI +EnumDirTree( + __in_opt HANDLE hProcess, + __in PCSTR RootPath, + __in PCSTR InputPathName, + __out_ecount_opt(MAX_PATH + 1) PSTR OutputPathBuffer, + __in_opt PENUMDIRTREE_CALLBACK cb, + __in_opt PVOID data + ); + +typedef BOOL +(CALLBACK *PENUMDIRTREE_CALLBACKW)( + __in PCWSTR FilePath, + __in_opt PVOID CallerData + ); + +BOOL +IMAGEAPI +EnumDirTreeW( + __in_opt HANDLE hProcess, + __in PCWSTR RootPath, + __in PCWSTR InputPathName, + __out_ecount_opt(MAX_PATH + 1) PWSTR OutputPathBuffer, + __in_opt PENUMDIRTREE_CALLBACKW cb, + __in_opt PVOID data + ); + +BOOL +IMAGEAPI +MakeSureDirectoryPathExists( + __in PCSTR DirPath + ); + +// +// UnDecorateSymbolName Flags +// + +#define UNDNAME_COMPLETE (0x0000) // Enable full undecoration +#define UNDNAME_NO_LEADING_UNDERSCORES (0x0001) // Remove leading underscores from MS extended keywords +#define UNDNAME_NO_MS_KEYWORDS (0x0002) // Disable expansion of MS extended keywords +#define UNDNAME_NO_FUNCTION_RETURNS (0x0004) // Disable expansion of return type for primary declaration +#define UNDNAME_NO_ALLOCATION_MODEL (0x0008) // Disable expansion of the declaration model +#define UNDNAME_NO_ALLOCATION_LANGUAGE (0x0010) // Disable expansion of the declaration language specifier +#define UNDNAME_NO_MS_THISTYPE (0x0020) // NYI Disable expansion of MS keywords on the 'this' type for primary declaration +#define UNDNAME_NO_CV_THISTYPE (0x0040) // NYI Disable expansion of CV modifiers on the 'this' type for primary declaration +#define UNDNAME_NO_THISTYPE (0x0060) // Disable all modifiers on the 'this' type +#define UNDNAME_NO_ACCESS_SPECIFIERS (0x0080) // Disable expansion of access specifiers for members +#define UNDNAME_NO_THROW_SIGNATURES (0x0100) // Disable expansion of 'throw-signatures' for functions and pointers to functions +#define UNDNAME_NO_MEMBER_TYPE (0x0200) // Disable expansion of 'static' or 'virtual'ness of members +#define UNDNAME_NO_RETURN_UDT_MODEL (0x0400) // Disable expansion of MS model for UDT returns +#define UNDNAME_32_BIT_DECODE (0x0800) // Undecorate 32-bit decorated names +#define UNDNAME_NAME_ONLY (0x1000) // Crack only the name for primary declaration; + // return just [scope::]name. Does expand template params +#define UNDNAME_NO_ARGUMENTS (0x2000) // Don't undecorate arguments to function +#define UNDNAME_NO_SPECIAL_SYMS (0x4000) // Don't undecorate special names (v-table, vcall, vector xxx, metatype, etc) + +DWORD +IMAGEAPI +WINAPI +UnDecorateSymbolName( + __in PCSTR name, + __out_ecount(maxStringLength) PSTR outputString, + __in DWORD maxStringLength, + __in DWORD flags + ); + +DWORD +IMAGEAPI +WINAPI +UnDecorateSymbolNameW( + __in PCWSTR name, + __out_ecount(maxStringLength) PWSTR outputString, + __in DWORD maxStringLength, + __in DWORD flags + ); + +// +// these values are used for synthesized file types +// that can be passed in as image headers instead of +// the standard ones from ntimage.h +// + +#define DBHHEADER_DEBUGDIRS 0x1 +#define DBHHEADER_CVMISC 0x2 +#define DBHHEADER_PDBGUID 0x3 +typedef struct _MODLOAD_DATA { + DWORD ssize; // size of this struct + DWORD ssig; // signature identifying the passed data + PVOID data; // pointer to passed data + DWORD size; // size of passed data + DWORD flags; // options +} MODLOAD_DATA, *PMODLOAD_DATA; + +typedef struct _MODLOAD_CVMISC { + DWORD oCV; // ofset to the codeview record + size_t cCV; // size of the codeview record + DWORD oMisc; // offset to the misc record + size_t cMisc; // size of the misc record + DWORD dtImage; // datetime stamp of the image + DWORD cImage; // size of the image +} MODLOAD_CVMISC, *PMODLOAD_CVMISC; + +typedef struct _MODLOAD_PDBGUID_PDBAGE { + GUID PdbGuid; // Pdb Guid + DWORD PdbAge; // Pdb Age +} MODLOAD_PDBGUID_PDBAGE, *PMODLOAD_PDBGUID_PDBAGE; + +// +// StackWalking API +// + +typedef enum { + AddrMode1616, + AddrMode1632, + AddrModeReal, + AddrModeFlat +} ADDRESS_MODE; + +typedef struct _tagADDRESS64 { + DWORD64 Offset; + WORD Segment; + ADDRESS_MODE Mode; +} ADDRESS64, *LPADDRESS64; + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define ADDRESS ADDRESS64 +#define LPADDRESS LPADDRESS64 +#else +typedef struct _tagADDRESS { + DWORD Offset; + WORD Segment; + ADDRESS_MODE Mode; +} ADDRESS, *LPADDRESS; + +__inline +void +Address32To64( + __in LPADDRESS a32, + __out LPADDRESS64 a64 + ) +{ + a64->Offset = (ULONG64)(LONG64)(LONG)a32->Offset; + a64->Segment = a32->Segment; + a64->Mode = a32->Mode; +} + +__inline +void +Address64To32( + __in LPADDRESS64 a64, + __out LPADDRESS a32 + ) +{ + a32->Offset = (ULONG)a64->Offset; + a32->Segment = a64->Segment; + a32->Mode = a64->Mode; +} +#endif + +// +// This structure is included in the STACKFRAME structure, +// and is used to trace through usermode callbacks in a thread's +// kernel stack. The values must be copied by the kernel debugger +// from the DBGKD_GET_VERSION and WAIT_STATE_CHANGE packets. +// + +// +// New KDHELP structure for 64 bit system support. +// This structure is preferred in new code. +// +typedef struct _KDHELP64 { + + // + // address of kernel thread object, as provided in the + // WAIT_STATE_CHANGE packet. + // + DWORD64 Thread; + + // + // offset in thread object to pointer to the current callback frame + // in kernel stack. + // + DWORD ThCallbackStack; + + // + // offset in thread object to pointer to the current callback backing + // store frame in kernel stack. + // + DWORD ThCallbackBStore; + + // + // offsets to values in frame: + // + // address of next callback frame + DWORD NextCallback; + + // address of saved frame pointer (if applicable) + DWORD FramePointer; + + + // + // Address of the kernel function that calls out to user mode + // + DWORD64 KiCallUserMode; + + // + // Address of the user mode dispatcher function + // + DWORD64 KeUserCallbackDispatcher; + + // + // Lowest kernel mode address + // + DWORD64 SystemRangeStart; + + // + // Address of the user mode exception dispatcher function. + // Added in API version 10. + // + DWORD64 KiUserExceptionDispatcher; + + // + // Stack bounds, added in API version 11. + // + DWORD64 StackBase; + DWORD64 StackLimit; + + DWORD64 Reserved[5]; + +} KDHELP64, *PKDHELP64; + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define KDHELP KDHELP64 +#define PKDHELP PKDHELP64 +#else +typedef struct _KDHELP { + + // + // address of kernel thread object, as provided in the + // WAIT_STATE_CHANGE packet. + // + DWORD Thread; + + // + // offset in thread object to pointer to the current callback frame + // in kernel stack. + // + DWORD ThCallbackStack; + + // + // offsets to values in frame: + // + // address of next callback frame + DWORD NextCallback; + + // address of saved frame pointer (if applicable) + DWORD FramePointer; + + // + // Address of the kernel function that calls out to user mode + // + DWORD KiCallUserMode; + + // + // Address of the user mode dispatcher function + // + DWORD KeUserCallbackDispatcher; + + // + // Lowest kernel mode address + // + DWORD SystemRangeStart; + + // + // offset in thread object to pointer to the current callback backing + // store frame in kernel stack. + // + DWORD ThCallbackBStore; + + // + // Address of the user mode exception dispatcher function. + // Added in API version 10. + // + DWORD KiUserExceptionDispatcher; + + // + // Stack bounds, added in API version 11. + // + DWORD StackBase; + DWORD StackLimit; + + DWORD Reserved[5]; + +} KDHELP, *PKDHELP; + +__inline +void +KdHelp32To64( + __in PKDHELP p32, + __out PKDHELP64 p64 + ) +{ + p64->Thread = p32->Thread; + p64->ThCallbackStack = p32->ThCallbackStack; + p64->NextCallback = p32->NextCallback; + p64->FramePointer = p32->FramePointer; + p64->KiCallUserMode = p32->KiCallUserMode; + p64->KeUserCallbackDispatcher = p32->KeUserCallbackDispatcher; + p64->SystemRangeStart = p32->SystemRangeStart; + p64->KiUserExceptionDispatcher = p32->KiUserExceptionDispatcher; + p64->StackBase = p32->StackBase; + p64->StackLimit = p32->StackLimit; +} +#endif + +typedef struct _tagSTACKFRAME64 { + ADDRESS64 AddrPC; // program counter + ADDRESS64 AddrReturn; // return address + ADDRESS64 AddrFrame; // frame pointer + ADDRESS64 AddrStack; // stack pointer + ADDRESS64 AddrBStore; // backing store pointer + PVOID FuncTableEntry; // pointer to pdata/fpo or NULL + DWORD64 Params[4]; // possible arguments to the function + BOOL Far; // WOW far call + BOOL Virtual; // is this a virtual frame? + DWORD64 Reserved[3]; + KDHELP64 KdHelp; +} STACKFRAME64, *LPSTACKFRAME64; + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define STACKFRAME STACKFRAME64 +#define LPSTACKFRAME LPSTACKFRAME64 +#else +typedef struct _tagSTACKFRAME { + ADDRESS AddrPC; // program counter + ADDRESS AddrReturn; // return address + ADDRESS AddrFrame; // frame pointer + ADDRESS AddrStack; // stack pointer + PVOID FuncTableEntry; // pointer to pdata/fpo or NULL + DWORD Params[4]; // possible arguments to the function + BOOL Far; // WOW far call + BOOL Virtual; // is this a virtual frame? + DWORD Reserved[3]; + KDHELP KdHelp; + ADDRESS AddrBStore; // backing store pointer +} STACKFRAME, *LPSTACKFRAME; +#endif + + +typedef +BOOL +(__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)( + __in HANDLE hProcess, + __in DWORD64 qwBaseAddress, + __out_bcount(nSize) PVOID lpBuffer, + __in DWORD nSize, + __out LPDWORD lpNumberOfBytesRead + ); + +typedef +PVOID +(__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64)( + __in HANDLE ahProcess, + __in DWORD64 AddrBase + ); + +typedef +DWORD64 +(__stdcall *PGET_MODULE_BASE_ROUTINE64)( + __in HANDLE hProcess, + __in DWORD64 Address + ); + +typedef +DWORD64 +(__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)( + __in HANDLE hProcess, + __in HANDLE hThread, + __in LPADDRESS64 lpaddr + ); + +BOOL +IMAGEAPI +StackWalk64( + __in DWORD MachineType, + __in HANDLE hProcess, + __in HANDLE hThread, + __inout LPSTACKFRAME64 StackFrame, + __inout PVOID ContextRecord, + __in_opt PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine, + __in_opt PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine, + __in_opt PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, + __in_opt PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) + +#define PREAD_PROCESS_MEMORY_ROUTINE PREAD_PROCESS_MEMORY_ROUTINE64 +#define PFUNCTION_TABLE_ACCESS_ROUTINE PFUNCTION_TABLE_ACCESS_ROUTINE64 +#define PGET_MODULE_BASE_ROUTINE PGET_MODULE_BASE_ROUTINE64 +#define PTRANSLATE_ADDRESS_ROUTINE PTRANSLATE_ADDRESS_ROUTINE64 + +#define StackWalk StackWalk64 + +#else + +typedef +BOOL +(__stdcall *PREAD_PROCESS_MEMORY_ROUTINE)( + __in HANDLE hProcess, + __in DWORD lpBaseAddress, + __out_bcount(nSize) PVOID lpBuffer, + __in DWORD nSize, + __out PDWORD lpNumberOfBytesRead + ); + +typedef +PVOID +(__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE)( + __in HANDLE hProcess, + __in DWORD AddrBase + ); + +typedef +DWORD +(__stdcall *PGET_MODULE_BASE_ROUTINE)( + __in HANDLE hProcess, + __in DWORD Address + ); + +typedef +DWORD +(__stdcall *PTRANSLATE_ADDRESS_ROUTINE)( + __in HANDLE hProcess, + __in HANDLE hThread, + __out LPADDRESS lpaddr + ); + +BOOL +IMAGEAPI +StackWalk( + DWORD MachineType, + __in HANDLE hProcess, + __in HANDLE hThread, + __inout LPSTACKFRAME StackFrame, + __inout PVOID ContextRecord, + __in_opt PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine, + __in_opt PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine, + __in_opt PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine, + __in_opt PTRANSLATE_ADDRESS_ROUTINE TranslateAddress + ); + +#endif + + +#define API_VERSION_NUMBER 11 + +typedef struct API_VERSION { + USHORT MajorVersion; + USHORT MinorVersion; + USHORT Revision; + USHORT Reserved; +} API_VERSION, *LPAPI_VERSION; + +LPAPI_VERSION +IMAGEAPI +ImagehlpApiVersion( + VOID + ); + +LPAPI_VERSION +IMAGEAPI +ImagehlpApiVersionEx( + __in LPAPI_VERSION AppVersion + ); + +DWORD +IMAGEAPI +GetTimestampForLoadedLibrary( + __in HMODULE Module + ); + +// +// typedefs for function pointers +// +typedef BOOL +(CALLBACK *PSYM_ENUMMODULES_CALLBACK64)( + __in PCSTR ModuleName, + __in DWORD64 BaseOfDll, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PSYM_ENUMMODULES_CALLBACKW64)( + __in PCWSTR ModuleName, + __in DWORD64 BaseOfDll, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PENUMLOADED_MODULES_CALLBACK64)( + __in PCSTR ModuleName, + __in DWORD64 ModuleBase, + __in ULONG ModuleSize, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PENUMLOADED_MODULES_CALLBACKW64)( + __in PCWSTR ModuleName, + __in DWORD64 ModuleBase, + __in ULONG ModuleSize, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK64)( + __in PCSTR SymbolName, + __in DWORD64 SymbolAddress, + __in ULONG SymbolSize, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK64W)( + __in PCWSTR SymbolName, + __in DWORD64 SymbolAddress, + __in ULONG SymbolSize, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PSYMBOL_REGISTERED_CALLBACK64)( + __in HANDLE hProcess, + __in ULONG ActionCode, + __in_opt ULONG64 CallbackData, + __in_opt ULONG64 UserContext + ); + +typedef +PVOID +(CALLBACK *PSYMBOL_FUNCENTRY_CALLBACK)( + __in HANDLE hProcess, + __in DWORD AddrBase, + __in_opt PVOID UserContext + ); + +typedef +PVOID +(CALLBACK *PSYMBOL_FUNCENTRY_CALLBACK64)( + __in HANDLE hProcess, + __in ULONG64 AddrBase, + __in ULONG64 UserContext + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) + +#define PSYM_ENUMMODULES_CALLBACK PSYM_ENUMMODULES_CALLBACK64 +#define PSYM_ENUMSYMBOLS_CALLBACK PSYM_ENUMSYMBOLS_CALLBACK64 +#define PSYM_ENUMSYMBOLS_CALLBACKW PSYM_ENUMSYMBOLS_CALLBACK64W +#define PENUMLOADED_MODULES_CALLBACK PENUMLOADED_MODULES_CALLBACK64 +#define PSYMBOL_REGISTERED_CALLBACK PSYMBOL_REGISTERED_CALLBACK64 +#define PSYMBOL_FUNCENTRY_CALLBACK PSYMBOL_FUNCENTRY_CALLBACK64 + +#else + +typedef BOOL +(CALLBACK *PSYM_ENUMMODULES_CALLBACK)( + __in PCSTR ModuleName, + __in ULONG BaseOfDll, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACK)( + __in PCSTR SymbolName, + __in ULONG SymbolAddress, + __in ULONG SymbolSize, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PSYM_ENUMSYMBOLS_CALLBACKW)( + __in PCWSTR SymbolName, + __in ULONG SymbolAddress, + __in ULONG SymbolSize, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PENUMLOADED_MODULES_CALLBACK)( + __in PCSTR ModuleName, + __in ULONG ModuleBase, + __in ULONG ModuleSize, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PSYMBOL_REGISTERED_CALLBACK)( + __in HANDLE hProcess, + __in ULONG ActionCode, + __in_opt PVOID CallbackData, + __in_opt PVOID UserContext + ); + +#endif + + +// values found in SYMBOL_INFO.Tag +// +// This was taken from cvconst.h and should +// not override any values found there. +// +// #define _NO_CVCONST_H_ if you don't +// have access to that file... + +#ifdef _NO_CVCONST_H + +// DIA enums + +enum SymTagEnum +{ + SymTagNull, + SymTagExe, + SymTagCompiland, + SymTagCompilandDetails, + SymTagCompilandEnv, + SymTagFunction, + SymTagBlock, + SymTagData, + SymTagAnnotation, + SymTagLabel, + SymTagPublicSymbol, + SymTagUDT, + SymTagEnum, + SymTagFunctionType, + SymTagPointerType, + SymTagArrayType, + SymTagBaseType, + SymTagTypedef, + SymTagBaseClass, + SymTagFriend, + SymTagFunctionArgType, + SymTagFuncDebugStart, + SymTagFuncDebugEnd, + SymTagUsingNamespace, + SymTagVTableShape, + SymTagVTable, + SymTagCustom, + SymTagThunk, + SymTagCustomType, + SymTagManagedType, + SymTagDimension, + SymTagMax +}; + +#endif + +// +// flags found in SYMBOL_INFO.Flags +// + +#define SYMFLAG_VALUEPRESENT 0x00000001 +#define SYMFLAG_REGISTER 0x00000008 +#define SYMFLAG_REGREL 0x00000010 +#define SYMFLAG_FRAMEREL 0x00000020 +#define SYMFLAG_PARAMETER 0x00000040 +#define SYMFLAG_LOCAL 0x00000080 +#define SYMFLAG_CONSTANT 0x00000100 +#define SYMFLAG_EXPORT 0x00000200 +#define SYMFLAG_FORWARDER 0x00000400 +#define SYMFLAG_FUNCTION 0x00000800 +#define SYMFLAG_VIRTUAL 0x00001000 +#define SYMFLAG_THUNK 0x00002000 +#define SYMFLAG_TLSREL 0x00004000 +#define SYMFLAG_SLOT 0x00008000 +#define SYMFLAG_ILREL 0x00010000 +#define SYMFLAG_METADATA 0x00020000 +#define SYMFLAG_CLR_TOKEN 0x00040000 + +// this resets SymNext/Prev to the beginning +// of the module passed in the address field + +#define SYMFLAG_RESET 0x80000000 + +// +// symbol type enumeration +// +typedef enum { + SymNone = 0, + SymCoff, + SymCv, + SymPdb, + SymExport, + SymDeferred, + SymSym, // .sym file + SymDia, + SymVirtual, + NumSymTypes +} SYM_TYPE; + +// +// symbol data structure +// + +typedef struct _IMAGEHLP_SYMBOL64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOL64) + DWORD64 Address; // virtual address including dll base address + DWORD Size; // estimated size of symbol, can be zero + DWORD Flags; // info about the symbols, see the SYMF defines + DWORD MaxNameLength; // maximum size of symbol name in 'Name' + CHAR Name[1]; // symbol name (null terminated string) +} IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64; + +typedef struct _IMAGEHLP_SYMBOL64_PACKAGE { + IMAGEHLP_SYMBOL64 sym; + CHAR name[MAX_SYM_NAME + 1]; +} IMAGEHLP_SYMBOL64_PACKAGE, *PIMAGEHLP_SYMBOL64_PACKAGE; + +typedef struct _IMAGEHLP_SYMBOLW64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOLW64) + DWORD64 Address; // virtual address including dll base address + DWORD Size; // estimated size of symbol, can be zero + DWORD Flags; // info about the symbols, see the SYMF defines + DWORD MaxNameLength; // maximum size of symbol name in 'Name' + WCHAR Name[1]; // symbol name (null terminated string) +} IMAGEHLP_SYMBOLW64, *PIMAGEHLP_SYMBOLW64; + +typedef struct _IMAGEHLP_SYMBOLW64_PACKAGE { + IMAGEHLP_SYMBOLW64 sym; + WCHAR name[MAX_SYM_NAME + 1]; +} IMAGEHLP_SYMBOLW64_PACKAGE, *PIMAGEHLP_SYMBOLW64_PACKAGE; + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) + + #define IMAGEHLP_SYMBOL IMAGEHLP_SYMBOL64 + #define PIMAGEHLP_SYMBOL PIMAGEHLP_SYMBOL64 + #define IMAGEHLP_SYMBOL_PACKAGE IMAGEHLP_SYMBOL64_PACKAGE + #define PIMAGEHLP_SYMBOL_PACKAGE PIMAGEHLP_SYMBOL64_PACKAGE + #define IMAGEHLP_SYMBOLW IMAGEHLP_SYMBOLW64 + #define PIMAGEHLP_SYMBOLW PIMAGEHLP_SYMBOLW64 + #define IMAGEHLP_SYMBOLW_PACKAGE IMAGEHLP_SYMBOLW64_PACKAGE + #define PIMAGEHLP_SYMBOLW_PACKAGE PIMAGEHLP_SYMBOLW64_PACKAGE + +#else + + typedef struct _IMAGEHLP_SYMBOL { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOL) + DWORD Address; // virtual address including dll base address + DWORD Size; // estimated size of symbol, can be zero + DWORD Flags; // info about the symbols, see the SYMF defines + DWORD MaxNameLength; // maximum size of symbol name in 'Name' + CHAR Name[1]; // symbol name (null terminated string) + } IMAGEHLP_SYMBOL, *PIMAGEHLP_SYMBOL; + + typedef struct _IMAGEHLP_SYMBOL_PACKAGE { + IMAGEHLP_SYMBOL sym; + CHAR name[MAX_SYM_NAME + 1]; + } IMAGEHLP_SYMBOL_PACKAGE, *PIMAGEHLP_SYMBOL_PACKAGE; + + typedef struct _IMAGEHLP_SYMBOLW { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_SYMBOLW) + DWORD Address; // virtual address including dll base address + DWORD Size; // estimated size of symbol, can be zero + DWORD Flags; // info about the symbols, see the SYMF defines + DWORD MaxNameLength; // maximum size of symbol name in 'Name' + WCHAR Name[1]; // symbol name (null terminated string) + } IMAGEHLP_SYMBOLW, *PIMAGEHLP_SYMBOLW; + + typedef struct _IMAGEHLP_SYMBOLW_PACKAGE { + IMAGEHLP_SYMBOLW sym; + WCHAR name[MAX_SYM_NAME + 1]; + } IMAGEHLP_SYMBOLW_PACKAGE, *PIMAGEHLP_SYMBOLW_PACKAGE; + +#endif + +// +// module data structure +// + +typedef struct _IMAGEHLP_MODULE64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) + DWORD64 BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + CHAR ModuleName[32]; // module name + CHAR ImageName[256]; // image name + CHAR LoadedImageName[256]; // symbol file name + // new elements: 07-Jun-2002 + CHAR LoadedPdbName[256]; // pdb file name + DWORD CVSig; // Signature of the CV record in the debug directories + CHAR CVData[MAX_PATH * 3]; // Contents of the CV record + DWORD PdbSig; // Signature of PDB + GUID PdbSig70; // Signature of PDB (VC 7 and up) + DWORD PdbAge; // DBI age of pdb + BOOL PdbUnmatched; // loaded an unmatched pdb + BOOL DbgUnmatched; // loaded an unmatched dbg + BOOL LineNumbers; // we have line number information + BOOL GlobalSymbols; // we have internal symbol information + BOOL TypeInfo; // we have type information + // new elements: 17-Dec-2003 + BOOL SourceIndexed; // pdb supports source server + BOOL Publics; // contains public symbols +} IMAGEHLP_MODULE64, *PIMAGEHLP_MODULE64; + +typedef struct _IMAGEHLP_MODULEW64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE64) + DWORD64 BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + WCHAR ModuleName[32]; // module name + WCHAR ImageName[256]; // image name + // new elements: 07-Jun-2002 + WCHAR LoadedImageName[256]; // symbol file name + WCHAR LoadedPdbName[256]; // pdb file name + DWORD CVSig; // Signature of the CV record in the debug directories + WCHAR CVData[MAX_PATH * 3]; // Contents of the CV record + DWORD PdbSig; // Signature of PDB + GUID PdbSig70; // Signature of PDB (VC 7 and up) + DWORD PdbAge; // DBI age of pdb + BOOL PdbUnmatched; // loaded an unmatched pdb + BOOL DbgUnmatched; // loaded an unmatched dbg + BOOL LineNumbers; // we have line number information + BOOL GlobalSymbols; // we have internal symbol information + BOOL TypeInfo; // we have type information + // new elements: 17-Dec-2003 + BOOL SourceIndexed; // pdb supports source server + BOOL Publics; // contains public symbols +} IMAGEHLP_MODULEW64, *PIMAGEHLP_MODULEW64; + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define IMAGEHLP_MODULE IMAGEHLP_MODULE64 +#define PIMAGEHLP_MODULE PIMAGEHLP_MODULE64 +#define IMAGEHLP_MODULEW IMAGEHLP_MODULEW64 +#define PIMAGEHLP_MODULEW PIMAGEHLP_MODULEW64 +#else +typedef struct _IMAGEHLP_MODULE { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE) + DWORD BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + CHAR ModuleName[32]; // module name + CHAR ImageName[256]; // image name + CHAR LoadedImageName[256]; // symbol file name +} IMAGEHLP_MODULE, *PIMAGEHLP_MODULE; + +typedef struct _IMAGEHLP_MODULEW { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_MODULE) + DWORD BaseOfImage; // base load address of module + DWORD ImageSize; // virtual size of the loaded module + DWORD TimeDateStamp; // date/time stamp from pe header + DWORD CheckSum; // checksum from the pe header + DWORD NumSyms; // number of symbols in the symbol table + SYM_TYPE SymType; // type of symbols loaded + WCHAR ModuleName[32]; // module name + WCHAR ImageName[256]; // image name + WCHAR LoadedImageName[256]; // symbol file name +} IMAGEHLP_MODULEW, *PIMAGEHLP_MODULEW; +#endif + +// +// source file line data structure +// + +typedef struct _IMAGEHLP_LINE64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) + PVOID Key; // internal + DWORD LineNumber; // line number in file + PCHAR FileName; // full filename + DWORD64 Address; // first instruction of line +} IMAGEHLP_LINE64, *PIMAGEHLP_LINE64; + +typedef struct _IMAGEHLP_LINEW64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) + PVOID Key; // internal + DWORD LineNumber; // line number in file + PWSTR FileName; // full filename + DWORD64 Address; // first instruction of line +} IMAGEHLP_LINEW64, *PIMAGEHLP_LINEW64; + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define IMAGEHLP_LINE IMAGEHLP_LINE64 +#define PIMAGEHLP_LINE PIMAGEHLP_LINE64 +#else +typedef struct _IMAGEHLP_LINE { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE) + PVOID Key; // internal + DWORD LineNumber; // line number in file + PCHAR FileName; // full filename + DWORD Address; // first instruction of line +} IMAGEHLP_LINE, *PIMAGEHLP_LINE; + +typedef struct _IMAGEHLP_LINEW { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_LINE64) + PVOID Key; // internal + DWORD LineNumber; // line number in file + PCHAR FileName; // full filename + DWORD64 Address; // first instruction of line +} IMAGEHLP_LINEW, *PIMAGEHLP_LINEW; +#endif + +// +// source file structure +// + +typedef struct _SOURCEFILE { + DWORD64 ModBase; // base address of loaded module + PCHAR FileName; // full filename of source +} SOURCEFILE, *PSOURCEFILE; + +typedef struct _SOURCEFILEW { + DWORD64 ModBase; // base address of loaded module + PWSTR FileName; // full filename of source +} SOURCEFILEW, *PSOURCEFILEW; + +// +// data structures used for registered symbol callbacks +// + +#define CBA_DEFERRED_SYMBOL_LOAD_START 0x00000001 +#define CBA_DEFERRED_SYMBOL_LOAD_COMPLETE 0x00000002 +#define CBA_DEFERRED_SYMBOL_LOAD_FAILURE 0x00000003 +#define CBA_SYMBOLS_UNLOADED 0x00000004 +#define CBA_DUPLICATE_SYMBOL 0x00000005 +#define CBA_READ_MEMORY 0x00000006 +#define CBA_DEFERRED_SYMBOL_LOAD_CANCEL 0x00000007 +#define CBA_SET_OPTIONS 0x00000008 +#define CBA_EVENT 0x00000010 +#define CBA_DEFERRED_SYMBOL_LOAD_PARTIAL 0x00000020 +#define CBA_DEBUG_INFO 0x10000000 +#define CBA_SRCSRV_INFO 0x20000000 +#define CBA_SRCSRV_EVENT 0x40000000 + +typedef struct _IMAGEHLP_CBA_READ_MEMORY { + DWORD64 addr; // address to read from + PVOID buf; // buffer to read to + DWORD bytes; // amount of bytes to read + DWORD *bytesread; // pointer to store amount of bytes read +} IMAGEHLP_CBA_READ_MEMORY, *PIMAGEHLP_CBA_READ_MEMORY; + +enum { + sevInfo = 0, + sevProblem, + sevAttn, + sevFatal, + sevMax // unused +}; + +#define EVENT_SRCSPEW_START 100 +#define EVENT_SRCSPEW 100 +#define EVENT_SRCSPEW_END 199 + +typedef struct _IMAGEHLP_CBA_EVENT { + DWORD severity; // values from sevInfo to sevFatal + DWORD code; // numerical code IDs the error + PCHAR desc; // may contain a text description of the error + PVOID object; // value dependant upon the error code +} IMAGEHLP_CBA_EVENT, *PIMAGEHLP_CBA_EVENT; + +typedef struct _IMAGEHLP_CBA_EVENTW { + DWORD severity; // values from sevInfo to sevFatal + DWORD code; // numerical code IDs the error + PCWSTR desc; // may contain a text description of the error + PVOID object; // value dependant upon the error code +} IMAGEHLP_CBA_EVENTW, *PIMAGEHLP_CBA_EVENTW; + +typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD64) + DWORD64 BaseOfImage; // base load address of module + DWORD CheckSum; // checksum from the pe header + DWORD TimeDateStamp; // date/time stamp from pe header + CHAR FileName[MAX_PATH]; // symbols file or image name + BOOLEAN Reparse; // load failure reparse + HANDLE hFile; // file handle, if passed + DWORD Flags; // +} IMAGEHLP_DEFERRED_SYMBOL_LOAD64, *PIMAGEHLP_DEFERRED_SYMBOL_LOAD64; + +typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOADW64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOADW64) + DWORD64 BaseOfImage; // base load address of module + DWORD CheckSum; // checksum from the pe header + DWORD TimeDateStamp; // date/time stamp from pe header + WCHAR FileName[MAX_PATH + 1]; // symbols file or image name + BOOLEAN Reparse; // load failure reparse + HANDLE hFile; // file handle, if passed + DWORD Flags; // +} IMAGEHLP_DEFERRED_SYMBOL_LOADW64, *PIMAGEHLP_DEFERRED_SYMBOL_LOADW64; + +#define DSLFLAG_MISMATCHED_PDB 0x1 +#define DSLFLAG_MISMATCHED_DBG 0x2 + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define IMAGEHLP_DEFERRED_SYMBOL_LOAD IMAGEHLP_DEFERRED_SYMBOL_LOAD64 +#define PIMAGEHLP_DEFERRED_SYMBOL_LOAD PIMAGEHLP_DEFERRED_SYMBOL_LOAD64 +#else +typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DEFERRED_SYMBOL_LOAD) + DWORD BaseOfImage; // base load address of module + DWORD CheckSum; // checksum from the pe header + DWORD TimeDateStamp; // date/time stamp from pe header + CHAR FileName[MAX_PATH]; // symbols file or image name + BOOLEAN Reparse; // load failure reparse + HANDLE hFile; // file handle, if passed +} IMAGEHLP_DEFERRED_SYMBOL_LOAD, *PIMAGEHLP_DEFERRED_SYMBOL_LOAD; +#endif + +typedef struct _IMAGEHLP_DUPLICATE_SYMBOL64 { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DUPLICATE_SYMBOL64) + DWORD NumberOfDups; // number of duplicates in the Symbol array + PIMAGEHLP_SYMBOL64 Symbol; // array of duplicate symbols + DWORD SelectedSymbol; // symbol selected (-1 to start) +} IMAGEHLP_DUPLICATE_SYMBOL64, *PIMAGEHLP_DUPLICATE_SYMBOL64; + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define IMAGEHLP_DUPLICATE_SYMBOL IMAGEHLP_DUPLICATE_SYMBOL64 +#define PIMAGEHLP_DUPLICATE_SYMBOL PIMAGEHLP_DUPLICATE_SYMBOL64 +#else +typedef struct _IMAGEHLP_DUPLICATE_SYMBOL { + DWORD SizeOfStruct; // set to sizeof(IMAGEHLP_DUPLICATE_SYMBOL) + DWORD NumberOfDups; // number of duplicates in the Symbol array + PIMAGEHLP_SYMBOL Symbol; // array of duplicate symbols + DWORD SelectedSymbol; // symbol selected (-1 to start) +} IMAGEHLP_DUPLICATE_SYMBOL, *PIMAGEHLP_DUPLICATE_SYMBOL; +#endif + +// If dbghelp ever needs to display graphical UI, it will use this as the parent window. + +BOOL +IMAGEAPI +SymSetParentWindow( + __in HWND hwnd + ); + +PCHAR +IMAGEAPI +SymSetHomeDirectory( + __in_opt HANDLE hProcess, + __in_opt PCSTR dir + ); + +PWSTR +IMAGEAPI +SymSetHomeDirectoryW( + __in_opt HANDLE hProcess, + __in_opt PCWSTR dir + ); + +PCHAR +IMAGEAPI +SymGetHomeDirectory( + __in DWORD type, + __out_ecount(size) PSTR dir, + __in size_t size + ); + +PWSTR +IMAGEAPI +SymGetHomeDirectoryW( + __in DWORD type, + __out_ecount(size) PWSTR dir, + __in size_t size + ); + +typedef enum { + hdBase = 0, // root directory for dbghelp + hdSym, // where symbols are stored + hdSrc, // where source is stored + hdMax // end marker +} DBG_HD_ENUM; + +typedef struct _OMAP { + ULONG rva; + ULONG rvaTo; +} OMAP, *POMAP; + +BOOL +IMAGEAPI +SymGetOmaps( + __in HANDLE hProcess, + __in DWORD64 BaseOfDll, + __out POMAP *OmapTo, + __out PDWORD64 cOmapTo, + __out POMAP *OmapFrom, + __out PDWORD64 cOmapFrom + ); + +// +// options that are set/returned by SymSetOptions() & SymGetOptions() +// these are used as a mask +// +#define SYMOPT_CASE_INSENSITIVE 0x00000001 +#define SYMOPT_UNDNAME 0x00000002 +#define SYMOPT_DEFERRED_LOADS 0x00000004 +#define SYMOPT_NO_CPP 0x00000008 +#define SYMOPT_LOAD_LINES 0x00000010 +#define SYMOPT_OMAP_FIND_NEAREST 0x00000020 +#define SYMOPT_LOAD_ANYTHING 0x00000040 +#define SYMOPT_IGNORE_CVREC 0x00000080 +#define SYMOPT_NO_UNQUALIFIED_LOADS 0x00000100 +#define SYMOPT_FAIL_CRITICAL_ERRORS 0x00000200 +#define SYMOPT_EXACT_SYMBOLS 0x00000400 +#define SYMOPT_ALLOW_ABSOLUTE_SYMBOLS 0x00000800 +#define SYMOPT_IGNORE_NT_SYMPATH 0x00001000 +#define SYMOPT_INCLUDE_32BIT_MODULES 0x00002000 +#define SYMOPT_PUBLICS_ONLY 0x00004000 +#define SYMOPT_NO_PUBLICS 0x00008000 +#define SYMOPT_AUTO_PUBLICS 0x00010000 +#define SYMOPT_NO_IMAGE_SEARCH 0x00020000 +#define SYMOPT_SECURE 0x00040000 +#define SYMOPT_NO_PROMPTS 0x00080000 +#define SYMOPT_OVERWRITE 0x00100000 +#define SYMOPT_IGNORE_IMAGEDIR 0x00200000 +#define SYMOPT_FLAT_DIRECTORY 0x00400000 +#define SYMOPT_FAVOR_COMPRESSED 0x00800000 +#define SYMOPT_ALLOW_ZERO_ADDRESS 0x01000000 +#define SYMOPT_DISABLE_SYMSRV_AUTODETECT 0x02000000 + +#define SYMOPT_DEBUG 0x80000000 + +DWORD +IMAGEAPI +SymSetOptions( + __in DWORD SymOptions + ); + +DWORD +IMAGEAPI +SymGetOptions( + VOID + ); + +BOOL +IMAGEAPI +SymCleanup( + __in HANDLE hProcess + ); + +BOOL +IMAGEAPI +SymMatchString( + __in PCSTR string, + __in PCSTR expression, + __in BOOL fCase + ); + +BOOL +IMAGEAPI +SymMatchStringA( + __in PCSTR string, + __in PCSTR expression, + __in BOOL fCase + ); + +BOOL +IMAGEAPI +SymMatchStringW( + __in PCWSTR string, + __in PCWSTR expression, + __in BOOL fCase + ); + +typedef BOOL +(CALLBACK *PSYM_ENUMSOURCEFILES_CALLBACK)( + __in PSOURCEFILE pSourceFile, + __in_opt PVOID UserContext + ); + +// for backwards compatibility - don't use this +#define PSYM_ENUMSOURCFILES_CALLBACK PSYM_ENUMSOURCEFILES_CALLBACK + +BOOL +IMAGEAPI +SymEnumSourceFiles( + __in HANDLE hProcess, + __in ULONG64 ModBase, + __in_opt PCSTR Mask, + __in PSYM_ENUMSOURCEFILES_CALLBACK cbSrcFiles, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PSYM_ENUMSOURCEFILES_CALLBACKW)( + __in PSOURCEFILEW pSourceFile, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumSourceFilesW( + __in HANDLE hProcess, + __in ULONG64 ModBase, + __in_opt PCWSTR Mask, + __in PSYM_ENUMSOURCEFILES_CALLBACKW cbSrcFiles, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumerateModules64( + __in HANDLE hProcess, + __in PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumerateModulesW64( + __in HANDLE hProcess, + __in PSYM_ENUMMODULES_CALLBACKW64 EnumModulesCallback, + __in_opt PVOID UserContext + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymEnumerateModules SymEnumerateModules64 +#else +BOOL +IMAGEAPI +SymEnumerateModules( + __in HANDLE hProcess, + __in PSYM_ENUMMODULES_CALLBACK EnumModulesCallback, + __in_opt PVOID UserContext + ); +#endif + +BOOL +IMAGEAPI +EnumerateLoadedModulesEx( + __in HANDLE hProcess, + __in PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +EnumerateLoadedModulesExW( + __in HANDLE hProcess, + __in PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +EnumerateLoadedModules64( + __in HANDLE hProcess, + __in PENUMLOADED_MODULES_CALLBACK64 EnumLoadedModulesCallback, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +EnumerateLoadedModulesW64( + __in HANDLE hProcess, + __in PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback, + __in_opt PVOID UserContext + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define EnumerateLoadedModules EnumerateLoadedModules64 +#else +BOOL +IMAGEAPI +EnumerateLoadedModules( + __in HANDLE hProcess, + __in PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback, + __in_opt PVOID UserContext + ); +#endif + +PVOID +IMAGEAPI +SymFunctionTableAccess64( + __in HANDLE hProcess, + __in DWORD64 AddrBase + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymFunctionTableAccess SymFunctionTableAccess64 +#else +PVOID +IMAGEAPI +SymFunctionTableAccess( + __in HANDLE hProcess, + __in DWORD AddrBase + ); +#endif + +BOOL +IMAGEAPI +SymGetUnwindInfo( + __in HANDLE hProcess, + __in DWORD64 Address, + __out_bcount_opt(*Size) PVOID Buffer, + __inout PULONG Size + ); + +BOOL +IMAGEAPI +SymGetModuleInfo64( + __in HANDLE hProcess, + __in DWORD64 qwAddr, + __out PIMAGEHLP_MODULE64 ModuleInfo + ); + +BOOL +IMAGEAPI +SymGetModuleInfoW64( + __in HANDLE hProcess, + __in DWORD64 qwAddr, + __out PIMAGEHLP_MODULEW64 ModuleInfo + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetModuleInfo SymGetModuleInfo64 +#define SymGetModuleInfoW SymGetModuleInfoW64 +#else +BOOL +IMAGEAPI +SymGetModuleInfo( + __in HANDLE hProcess, + __in DWORD dwAddr, + __out PIMAGEHLP_MODULE ModuleInfo + ); + +BOOL +IMAGEAPI +SymGetModuleInfoW( + __in HANDLE hProcess, + __in DWORD dwAddr, + __out PIMAGEHLP_MODULEW ModuleInfo + ); +#endif + +DWORD64 +IMAGEAPI +SymGetModuleBase64( + __in HANDLE hProcess, + __in DWORD64 qwAddr + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetModuleBase SymGetModuleBase64 +#else +DWORD +IMAGEAPI +SymGetModuleBase( + __in HANDLE hProcess, + __in DWORD dwAddr + ); +#endif + +typedef struct _SRCCODEINFO { + DWORD SizeOfStruct; // set to sizeof(SRCCODEINFO) + PVOID Key; // not used + DWORD64 ModBase; // base address of module this applies to + CHAR Obj[MAX_PATH + 1]; // the object file within the module + CHAR FileName[MAX_PATH + 1]; // full filename + DWORD LineNumber; // line number in file + DWORD64 Address; // first instruction of line +} SRCCODEINFO, *PSRCCODEINFO; + +typedef struct _SRCCODEINFOW { + DWORD SizeOfStruct; // set to sizeof(SRCCODEINFO) + PVOID Key; // not used + DWORD64 ModBase; // base address of module this applies to + WCHAR Obj[MAX_PATH + 1]; // the object file within the module + WCHAR FileName[MAX_PATH + 1]; // full filename + DWORD LineNumber; // line number in file + DWORD64 Address; // first instruction of line +} SRCCODEINFOW, *PSRCCODEINFOW; + +typedef BOOL +(CALLBACK *PSYM_ENUMLINES_CALLBACK)( + __in PSRCCODEINFO LineInfo, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumLines( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCSTR Obj, + __in_opt PCSTR File, + __in PSYM_ENUMLINES_CALLBACK EnumLinesCallback, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PSYM_ENUMLINES_CALLBACKW)( + __in PSRCCODEINFOW LineInfo, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumLinesW( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCWSTR Obj, + __in_opt PCWSTR File, + __in PSYM_ENUMLINES_CALLBACKW EnumLinesCallback, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymGetLineFromAddr64( + __in HANDLE hProcess, + __in DWORD64 qwAddr, + __out PDWORD pdwDisplacement, + __out PIMAGEHLP_LINE64 Line64 + ); + +BOOL +IMAGEAPI +SymGetLineFromAddrW64( + __in HANDLE hProcess, + __in DWORD64 dwAddr, + __out PDWORD pdwDisplacement, + __out PIMAGEHLP_LINEW64 Line + ); + +BOOL +IMAGEAPI +SymEnumSourceLines( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCSTR Obj, + __in_opt PCSTR File, + __in_opt DWORD Line, + __in DWORD Flags, + __in PSYM_ENUMLINES_CALLBACK EnumLinesCallback, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumSourceLinesW( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCWSTR Obj, + __in_opt PCWSTR File, + __in_opt DWORD Line, + __in DWORD Flags, + __in PSYM_ENUMLINES_CALLBACKW EnumLinesCallback, + __in_opt PVOID UserContext + ); + +// flags for SymEnumSourceLines + +#define ESLFLAG_FULLPATH 0x1 +#define ESLFLAG_NEAREST 0x2 +#define ESLFLAG_PREV 0x4 +#define ESLFLAG_NEXT 0x8 + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetLineFromAddr SymGetLineFromAddr64 +#define SymGetLineFromAddrW SymGetLineFromAddrW64 +#else +BOOL +IMAGEAPI +SymGetLineFromAddr( + __in HANDLE hProcess, + __in DWORD dwAddr, + __out PDWORD pdwDisplacement, + __out PIMAGEHLP_LINE Line + ); + +BOOL +IMAGEAPI +SymGetLineFromAddrW( + __in HANDLE hProcess, + __in DWORD dwAddr, + __out PDWORD pdwDisplacement, + __out PIMAGEHLP_LINEW Line + ); +#endif + +BOOL +IMAGEAPI +SymGetLineFromName64( + __in HANDLE hProcess, + __in_opt PCSTR ModuleName, + __in_opt PCSTR FileName, + __in DWORD dwLineNumber, + __out PLONG plDisplacement, + __inout PIMAGEHLP_LINE64 Line + ); + +BOOL +IMAGEAPI +SymGetLineFromNameW64( + __in HANDLE hProcess, + __in_opt PCWSTR ModuleName, + __in_opt PCWSTR FileName, + __in DWORD dwLineNumber, + __out PLONG plDisplacement, + __inout PIMAGEHLP_LINEW64 Line + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetLineFromName SymGetLineFromName64 +#else +BOOL +IMAGEAPI +SymGetLineFromName( + __in HANDLE hProcess, + __in_opt PCSTR ModuleName, + __in_opt PCSTR FileName, + __in DWORD dwLineNumber, + __out PLONG plDisplacement, + __inout PIMAGEHLP_LINE Line + ); +#endif + +BOOL +IMAGEAPI +SymGetLineNext64( + __in HANDLE hProcess, + __inout PIMAGEHLP_LINE64 Line + ); + +BOOL +IMAGEAPI +SymGetLineNextW64( + __in HANDLE hProcess, + __inout PIMAGEHLP_LINEW64 Line + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetLineNext SymGetLineNext64 +#else +BOOL +IMAGEAPI +SymGetLineNext( + __in HANDLE hProcess, + __inout PIMAGEHLP_LINE Line + ); + +BOOL +IMAGEAPI +SymGetLineNextW( + __in HANDLE hProcess, + __inout PIMAGEHLP_LINEW Line + ); +#endif + +BOOL +IMAGEAPI +SymGetLinePrev64( + __in HANDLE hProcess, + __inout PIMAGEHLP_LINE64 Line + ); + +BOOL +IMAGEAPI +SymGetLinePrevW64( + __in HANDLE hProcess, + __inout PIMAGEHLP_LINEW64 Line + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetLinePrev SymGetLinePrev64 +#else +BOOL +IMAGEAPI +SymGetLinePrev( + __in HANDLE hProcess, + __inout PIMAGEHLP_LINE Line + ); + +BOOL +IMAGEAPI +SymGetLinePrevW( + __in HANDLE hProcess, + __inout PIMAGEHLP_LINEW Line + ); +#endif + +ULONG +IMAGEAPI +SymGetFileLineOffsets64( + __in HANDLE hProcess, + __in_opt PCSTR ModuleName, + __in PCSTR FileName, + __out_ecount(BufferLines) PDWORD64 Buffer, + __in ULONG BufferLines + ); + +BOOL +IMAGEAPI +SymMatchFileName( + __in PCSTR FileName, + __in PCSTR Match, + __deref_opt_out PSTR *FileNameStop, + __deref_opt_out PSTR *MatchStop + ); + +BOOL +IMAGEAPI +SymMatchFileNameW( + __in PCWSTR FileName, + __in PCWSTR Match, + __deref_opt_out PWSTR *FileNameStop, + __deref_opt_out PWSTR *MatchStop + ); + +BOOL +IMAGEAPI +SymGetSourceFile( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCSTR Params, + __in PCSTR FileSpec, + __out_ecount(Size) PSTR FilePath, + __in DWORD Size + ); + +BOOL +IMAGEAPI +SymGetSourceFileW( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCWSTR Params, + __in PCWSTR FileSpec, + __out_ecount(Size) PWSTR FilePath, + __in DWORD Size + ); + +BOOL +IMAGEAPI +SymGetSourceFileToken( + __in HANDLE hProcess, + __in ULONG64 Base, + __in PCSTR FileSpec, + __deref_out PVOID *Token, + __out DWORD *Size + ); + +BOOL +IMAGEAPI +SymGetSourceFileTokenW( + __in HANDLE hProcess, + __in ULONG64 Base, + __in PCWSTR FileSpec, + __deref_out PVOID *Token, + __out DWORD *Size + ); + +BOOL +IMAGEAPI +SymGetSourceFileFromToken( + __in HANDLE hProcess, + __in PVOID Token, + __in_opt PCSTR Params, + __out_ecount(Size) PSTR FilePath, + __in DWORD Size + ); + +BOOL +IMAGEAPI +SymGetSourceFileFromTokenW( + __in HANDLE hProcess, + __in PVOID Token, + __in_opt PCWSTR Params, + __out_ecount(Size) PWSTR FilePath, + __in DWORD Size + ); + +BOOL +IMAGEAPI +SymGetSourceVarFromToken( + __in HANDLE hProcess, + __in PVOID Token, + __in_opt PCSTR Params, + __in PCSTR VarName, + __out_ecount(Size) PSTR Value, + __in DWORD Size + ); + +BOOL +IMAGEAPI +SymGetSourceVarFromTokenW( + __in HANDLE hProcess, + __in PVOID Token, + __in_opt PCWSTR Params, + __in PCWSTR VarName, + __out_ecount(Size) PWSTR Value, + __in DWORD Size + ); + +typedef BOOL (CALLBACK *PENUMSOURCEFILETOKENSCALLBACK)(__in PVOID token, __in size_t size); + +BOOL +IMAGEAPI +SymEnumSourceFileTokens( + __in HANDLE hProcess, + __in ULONG64 Base, + __in PENUMSOURCEFILETOKENSCALLBACK Callback + ); + +BOOL +IMAGEAPI +SymInitialize( + __in HANDLE hProcess, + __in_opt PCSTR UserSearchPath, + __in BOOL fInvadeProcess + ); + +BOOL +IMAGEAPI +SymInitializeW( + __in HANDLE hProcess, + __in_opt PCWSTR UserSearchPath, + __in BOOL fInvadeProcess + ); + +BOOL +IMAGEAPI +SymGetSearchPath( + __in HANDLE hProcess, + __out_ecount(SearchPathLength) PSTR SearchPath, + __in DWORD SearchPathLength + ); + +BOOL +IMAGEAPI +SymGetSearchPathW( + __in HANDLE hProcess, + __out_ecount(SearchPathLength) PWSTR SearchPath, + __in DWORD SearchPathLength + ); + +BOOL +IMAGEAPI +SymSetSearchPath( + __in HANDLE hProcess, + __in_opt PCSTR SearchPath + ); + +BOOL +IMAGEAPI +SymSetSearchPathW( + __in HANDLE hProcess, + __in_opt PCWSTR SearchPath + ); + +#define SLMFLAG_VIRTUAL 0x1 +#define SLMFLAG_ALT_INDEX 0x2 +#define SLMFLAG_NO_SYMBOLS 0x4 + +DWORD64 +IMAGEAPI +SymLoadModuleEx( + __in HANDLE hProcess, + __in_opt HANDLE hFile, + __in_opt PCSTR ImageName, + __in_opt PCSTR ModuleName, + __in DWORD64 BaseOfDll, + __in DWORD DllSize, + __in_opt PMODLOAD_DATA Data, + __in_opt DWORD Flags + ); + +DWORD64 +IMAGEAPI +SymLoadModuleExW( + __in HANDLE hProcess, + __in_opt HANDLE hFile, + __in_opt PCWSTR ImageName, + __in_opt PCWSTR ModuleName, + __in DWORD64 BaseOfDll, + __in DWORD DllSize, + __in_opt PMODLOAD_DATA Data, + __in_opt DWORD Flags + ); + +BOOL +IMAGEAPI +SymUnloadModule64( + __in HANDLE hProcess, + __in DWORD64 BaseOfDll + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymUnloadModule SymUnloadModule64 +#else +BOOL +IMAGEAPI +SymUnloadModule( + __in HANDLE hProcess, + __in DWORD BaseOfDll + ); +#endif + +BOOL +IMAGEAPI +SymUnDName64( + __in PIMAGEHLP_SYMBOL64 sym, // Symbol to undecorate + __out_ecount(UnDecNameLength) PSTR UnDecName, // Buffer to store undecorated name in + __in DWORD UnDecNameLength // Size of the buffer + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymUnDName SymUnDName64 +#else +BOOL +IMAGEAPI +SymUnDName( + __in PIMAGEHLP_SYMBOL sym, // Symbol to undecorate + __out_ecount(UnDecNameLength) PSTR UnDecName, // Buffer to store undecorated name in + __in DWORD UnDecNameLength // Size of the buffer + ); +#endif + +BOOL +IMAGEAPI +SymRegisterCallback64( + __in HANDLE hProcess, + __in PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, + __in ULONG64 UserContext + ); + +BOOL +IMAGEAPI +SymRegisterCallbackW64( + __in HANDLE hProcess, + __in PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction, + __in ULONG64 UserContext + ); + +BOOL +IMAGEAPI +SymRegisterFunctionEntryCallback64( + __in HANDLE hProcess, + __in PSYMBOL_FUNCENTRY_CALLBACK64 CallbackFunction, + __in ULONG64 UserContext + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymRegisterCallback SymRegisterCallback64 +#define SymRegisterFunctionEntryCallback SymRegisterFunctionEntryCallback64 +#else +BOOL +IMAGEAPI +SymRegisterCallback( + __in HANDLE hProcess, + __in PSYMBOL_REGISTERED_CALLBACK CallbackFunction, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymRegisterFunctionEntryCallback( + __in HANDLE hProcess, + __in PSYMBOL_FUNCENTRY_CALLBACK CallbackFunction, + __in_opt PVOID UserContext + ); +#endif + + +typedef struct _IMAGEHLP_SYMBOL_SRC { + DWORD sizeofstruct; + DWORD type; + char file[MAX_PATH]; +} IMAGEHLP_SYMBOL_SRC, *PIMAGEHLP_SYMBOL_SRC; + +typedef struct _MODULE_TYPE_INFO { // AKA TYPTYP + USHORT dataLength; + USHORT leaf; + BYTE data[1]; +} MODULE_TYPE_INFO, *PMODULE_TYPE_INFO; + +typedef struct _SYMBOL_INFO { + ULONG SizeOfStruct; + ULONG TypeIndex; // Type Index of symbol + ULONG64 Reserved[2]; + ULONG Index; + ULONG Size; + ULONG64 ModBase; // Base Address of module comtaining this symbol + ULONG Flags; + ULONG64 Value; // Value of symbol, ValuePresent should be 1 + ULONG64 Address; // Address of symbol including base address of module + ULONG Register; // register holding value or pointer to value + ULONG Scope; // scope of the symbol + ULONG Tag; // pdb classification + ULONG NameLen; // Actual length of name + ULONG MaxNameLen; + CHAR Name[1]; // Name of symbol +} SYMBOL_INFO, *PSYMBOL_INFO; + +typedef struct _SYMBOL_INFO_PACKAGE { + SYMBOL_INFO si; + CHAR name[MAX_SYM_NAME + 1]; +} SYMBOL_INFO_PACKAGE, *PSYMBOL_INFO_PACKAGE; + +typedef struct _SYMBOL_INFOW { + ULONG SizeOfStruct; + ULONG TypeIndex; // Type Index of symbol + ULONG64 Reserved[2]; + ULONG Index; + ULONG Size; + ULONG64 ModBase; // Base Address of module comtaining this symbol + ULONG Flags; + ULONG64 Value; // Value of symbol, ValuePresent should be 1 + ULONG64 Address; // Address of symbol including base address of module + ULONG Register; // register holding value or pointer to value + ULONG Scope; // scope of the symbol + ULONG Tag; // pdb classification + ULONG NameLen; // Actual length of name + ULONG MaxNameLen; + WCHAR Name[1]; // Name of symbol +} SYMBOL_INFOW, *PSYMBOL_INFOW; + +typedef struct _SYMBOL_INFO_PACKAGEW { + SYMBOL_INFOW si; + WCHAR name[MAX_SYM_NAME + 1]; +} SYMBOL_INFO_PACKAGEW, *PSYMBOL_INFO_PACKAGEW; + +typedef struct _IMAGEHLP_STACK_FRAME +{ + ULONG64 InstructionOffset; + ULONG64 ReturnOffset; + ULONG64 FrameOffset; + ULONG64 StackOffset; + ULONG64 BackingStoreOffset; + ULONG64 FuncTableEntry; + ULONG64 Params[4]; + ULONG64 Reserved[5]; + BOOL Virtual; + ULONG Reserved2; +} IMAGEHLP_STACK_FRAME, *PIMAGEHLP_STACK_FRAME; + +typedef VOID IMAGEHLP_CONTEXT, *PIMAGEHLP_CONTEXT; + + +BOOL +IMAGEAPI +SymSetContext( + __in HANDLE hProcess, + __in PIMAGEHLP_STACK_FRAME StackFrame, + __in_opt PIMAGEHLP_CONTEXT Context + ); + +BOOL +IMAGEAPI +SymSetScopeFromAddr( + __in HANDLE hProcess, + __in ULONG64 Address + ); + +BOOL +IMAGEAPI +SymSetScopeFromIndex( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in DWORD Index + ); + +typedef BOOL +(CALLBACK *PSYM_ENUMPROCESSES_CALLBACK)( + __in HANDLE hProcess, + __in PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumProcesses( + __in PSYM_ENUMPROCESSES_CALLBACK EnumProcessesCallback, + __in PVOID UserContext + ); + +BOOL +IMAGEAPI +SymFromAddr( + __in HANDLE hProcess, + __in DWORD64 Address, + __out_opt PDWORD64 Displacement, + __inout PSYMBOL_INFO Symbol + ); + +BOOL +IMAGEAPI +SymFromAddrW( + __in HANDLE hProcess, + __in DWORD64 Address, + __out_opt PDWORD64 Displacement, + __inout PSYMBOL_INFOW Symbol + ); + +BOOL +IMAGEAPI +SymFromToken( + __in HANDLE hProcess, + __in DWORD64 Base, + __in DWORD Token, + __inout PSYMBOL_INFO Symbol + ); + +BOOL +IMAGEAPI +SymFromTokenW( + __in HANDLE hProcess, + __in DWORD64 Base, + __in DWORD Token, + __inout PSYMBOL_INFOW Symbol + ); + +BOOL +IMAGEAPI +SymNext( + __in HANDLE hProcess, + __inout PSYMBOL_INFO si + ); + +BOOL +IMAGEAPI +SymNextW( + __in HANDLE hProcess, + __inout PSYMBOL_INFOW siw + ); + +BOOL +IMAGEAPI +SymPrev( + __in HANDLE hProcess, + __inout PSYMBOL_INFO si + ); + +BOOL +IMAGEAPI +SymPrevW( + __in HANDLE hProcess, + __inout PSYMBOL_INFOW siw + ); + +// While SymFromName will provide a symbol from a name, +// SymEnumSymbols can provide the same matching information +// for ALL symbols with a matching name, even regular +// expressions. That way you can search across modules +// and differentiate between identically named symbols. + +BOOL +IMAGEAPI +SymFromName( + __in HANDLE hProcess, + __in PCSTR Name, + __inout PSYMBOL_INFO Symbol + ); + +BOOL +IMAGEAPI +SymFromNameW( + __in HANDLE hProcess, + __in PCWSTR Name, + __inout PSYMBOL_INFOW Symbol + ); + +typedef BOOL +(CALLBACK *PSYM_ENUMERATESYMBOLS_CALLBACK)( + __in PSYMBOL_INFO pSymInfo, + __in ULONG SymbolSize, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumSymbols( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt PCSTR Mask, + __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, + __in_opt PVOID UserContext + ); + +typedef BOOL +(CALLBACK *PSYM_ENUMERATESYMBOLS_CALLBACKW)( + __in PSYMBOL_INFOW pSymInfo, + __in ULONG SymbolSize, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumSymbolsW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt PCWSTR Mask, + __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumSymbolsForAddr( + __in HANDLE hProcess, + __in DWORD64 Address, + __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumSymbolsForAddrW( + __in HANDLE hProcess, + __in DWORD64 Address, + __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, + __in_opt PVOID UserContext + ); + +#define SYMSEARCH_MASKOBJS 0x01 // used internally to implement other APIs +#define SYMSEARCH_RECURSE 0X02 // recurse scopes +#define SYMSEARCH_GLOBALSONLY 0X04 // search only for global symbols +#define SYMSEARCH_ALLITEMS 0X08 // search for everything in the pdb, not just normal scoped symbols + +BOOL +IMAGEAPI +SymSearch( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt DWORD Index, + __in_opt DWORD SymTag, + __in_opt PCSTR Mask, + __in_opt DWORD64 Address, + __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, + __in_opt PVOID UserContext, + __in DWORD Options + ); + +BOOL +IMAGEAPI +SymSearchW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt DWORD Index, + __in_opt DWORD SymTag, + __in_opt PCWSTR Mask, + __in_opt DWORD64 Address, + __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, + __in_opt PVOID UserContext, + __in DWORD Options + ); + +BOOL +IMAGEAPI +SymGetScope( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in DWORD Index, + __inout PSYMBOL_INFO Symbol + ); + +BOOL +IMAGEAPI +SymGetScopeW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in DWORD Index, + __inout PSYMBOL_INFOW Symbol + ); + +BOOL +IMAGEAPI +SymFromIndex( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in DWORD Index, + __inout PSYMBOL_INFO Symbol + ); + +BOOL +IMAGEAPI +SymFromIndexW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in DWORD Index, + __inout PSYMBOL_INFOW Symbol + ); + +typedef enum _IMAGEHLP_SYMBOL_TYPE_INFO { + TI_GET_SYMTAG, + TI_GET_SYMNAME, + TI_GET_LENGTH, + TI_GET_TYPE, + TI_GET_TYPEID, + TI_GET_BASETYPE, + TI_GET_ARRAYINDEXTYPEID, + TI_FINDCHILDREN, + TI_GET_DATAKIND, + TI_GET_ADDRESSOFFSET, + TI_GET_OFFSET, + TI_GET_VALUE, + TI_GET_COUNT, + TI_GET_CHILDRENCOUNT, + TI_GET_BITPOSITION, + TI_GET_VIRTUALBASECLASS, + TI_GET_VIRTUALTABLESHAPEID, + TI_GET_VIRTUALBASEPOINTEROFFSET, + TI_GET_CLASSPARENTID, + TI_GET_NESTED, + TI_GET_SYMINDEX, + TI_GET_LEXICALPARENT, + TI_GET_ADDRESS, + TI_GET_THISADJUST, + TI_GET_UDTKIND, + TI_IS_EQUIV_TO, + TI_GET_CALLING_CONVENTION, + TI_IS_CLOSE_EQUIV_TO, + TI_GTIEX_REQS_VALID, + TI_GET_VIRTUALBASEOFFSET, + TI_GET_VIRTUALBASEDISPINDEX, + TI_GET_IS_REFERENCE, + TI_GET_INDIRECTVIRTUALBASECLASS, + IMAGEHLP_SYMBOL_TYPE_INFO_MAX, +} IMAGEHLP_SYMBOL_TYPE_INFO; + +typedef struct _TI_FINDCHILDREN_PARAMS { + ULONG Count; + ULONG Start; + ULONG ChildId[1]; +} TI_FINDCHILDREN_PARAMS; + +BOOL +IMAGEAPI +SymGetTypeInfo( + __in HANDLE hProcess, + __in DWORD64 ModBase, + __in ULONG TypeId, + __in IMAGEHLP_SYMBOL_TYPE_INFO GetType, + __out PVOID pInfo + ); + +#define IMAGEHLP_GET_TYPE_INFO_UNCACHED 0x00000001 +#define IMAGEHLP_GET_TYPE_INFO_CHILDREN 0x00000002 + +typedef struct _IMAGEHLP_GET_TYPE_INFO_PARAMS { + IN ULONG SizeOfStruct; + IN ULONG Flags; + IN ULONG NumIds; + IN PULONG TypeIds; + IN ULONG64 TagFilter; + IN ULONG NumReqs; + IN IMAGEHLP_SYMBOL_TYPE_INFO* ReqKinds; + IN PULONG_PTR ReqOffsets; + IN PULONG ReqSizes; + IN ULONG_PTR ReqStride; + IN ULONG_PTR BufferSize; + OUT PVOID Buffer; + OUT ULONG EntriesMatched; + OUT ULONG EntriesFilled; + OUT ULONG64 TagsFound; + OUT ULONG64 AllReqsValid; + IN ULONG NumReqsValid; + OUT PULONG64 ReqsValid OPTIONAL; +} IMAGEHLP_GET_TYPE_INFO_PARAMS, *PIMAGEHLP_GET_TYPE_INFO_PARAMS; + +BOOL +IMAGEAPI +SymGetTypeInfoEx( + __in HANDLE hProcess, + __in DWORD64 ModBase, + __inout PIMAGEHLP_GET_TYPE_INFO_PARAMS Params + ); + +BOOL +IMAGEAPI +SymEnumTypes( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumTypesW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumTypesByName( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt PCSTR mask, + __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymEnumTypesByNameW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt PCWSTR mask, + __in PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback, + __in_opt PVOID UserContext + ); + +BOOL +IMAGEAPI +SymGetTypeFromName( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PCSTR Name, + __inout PSYMBOL_INFO Symbol + ); + +BOOL +IMAGEAPI +SymGetTypeFromNameW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PCWSTR Name, + __inout PSYMBOL_INFOW Symbol + ); + +BOOL +IMAGEAPI +SymAddSymbol( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PCSTR Name, + __in DWORD64 Address, + __in DWORD Size, + __in DWORD Flags + ); + +BOOL +IMAGEAPI +SymAddSymbolW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PCWSTR Name, + __in DWORD64 Address, + __in DWORD Size, + __in DWORD Flags + ); + +BOOL +IMAGEAPI +SymDeleteSymbol( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt PCSTR Name, + __in DWORD64 Address, + __in DWORD Flags + ); + +BOOL +IMAGEAPI +SymDeleteSymbolW( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in_opt PCWSTR Name, + __in DWORD64 Address, + __in DWORD Flags + ); + +BOOL +IMAGEAPI +SymRefreshModuleList( + __in HANDLE hProcess + ); + +BOOL +IMAGEAPI +SymAddSourceStream( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCSTR StreamFile, + __in_bcount_opt(Size) PBYTE Buffer, + __in size_t Size + ); + +typedef BOOL (WINAPI *SYMADDSOURCESTREAM)(HANDLE, ULONG64, PCSTR, PBYTE, size_t); + +BOOL +IMAGEAPI +SymAddSourceStreamA( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCSTR StreamFile, + __in_bcount_opt(Size) PBYTE Buffer, + __in size_t Size + ); + +typedef BOOL (WINAPI *SYMADDSOURCESTREAMA)(HANDLE, ULONG64, PCSTR, PBYTE, size_t); + +BOOL +IMAGEAPI +SymAddSourceStreamW( + __in HANDLE hProcess, + __in ULONG64 Base, + __in_opt PCWSTR FileSpec, + __in_bcount_opt(Size) PBYTE Buffer, + __in size_t Size + ); + +BOOL +IMAGEAPI +SymSrvIsStoreW( + __in_opt HANDLE hProcess, + __in PCWSTR path + ); + +BOOL +IMAGEAPI +SymSrvIsStore( + __in_opt HANDLE hProcess, + __in PCSTR path + ); + +PCSTR +IMAGEAPI +SymSrvDeltaName( + __in HANDLE hProcess, + __in_opt PCSTR SymPath, + __in PCSTR Type, + __in PCSTR File1, + __in PCSTR File2 + ); + +PCWSTR +IMAGEAPI +SymSrvDeltaNameW( + __in HANDLE hProcess, + __in_opt PCWSTR SymPath, + __in PCWSTR Type, + __in PCWSTR File1, + __in PCWSTR File2 + ); + +PCSTR +IMAGEAPI +SymSrvGetSupplement( + __in HANDLE hProcess, + __in_opt PCSTR SymPath, + __in PCSTR Node, + __in PCSTR File + ); + +PCWSTR +IMAGEAPI +SymSrvGetSupplementW( + __in HANDLE hProcess, + __in_opt PCWSTR SymPath, + __in PCWSTR Node, + __in PCWSTR File + ); + +BOOL +IMAGEAPI +SymSrvGetFileIndexes( + __in PCSTR File, + __out GUID *Id, + __out PDWORD Val1, + __out_opt PDWORD Val2, + __in DWORD Flags + ); + +BOOL +IMAGEAPI +SymSrvGetFileIndexesW( + __in PCWSTR File, + __out GUID *Id, + __out PDWORD Val1, + __out_opt PDWORD Val2, + __in DWORD Flags + ); + +BOOL +IMAGEAPI +SymSrvGetFileIndexStringW( + __in HANDLE hProcess, + __in_opt PCWSTR SrvPath, + __in PCWSTR File, + __out_ecount(Size) PWSTR Index, + __in size_t Size, + __in DWORD Flags + ); + +BOOL +IMAGEAPI +SymSrvGetFileIndexString( + __in HANDLE hProcess, + __in_opt PCSTR SrvPath, + __in PCSTR File, + __out_ecount(Size) PSTR Index, + __in size_t Size, + __in DWORD Flags + ); + +typedef struct { + DWORD sizeofstruct; + char file[MAX_PATH +1]; + BOOL stripped; + DWORD timestamp; + DWORD size; + char dbgfile[MAX_PATH +1]; + char pdbfile[MAX_PATH + 1]; + GUID guid; + DWORD sig; + DWORD age; +} SYMSRV_INDEX_INFO, *PSYMSRV_INDEX_INFO; + +typedef struct { + DWORD sizeofstruct; + WCHAR file[MAX_PATH +1]; + BOOL stripped; + DWORD timestamp; + DWORD size; + WCHAR dbgfile[MAX_PATH +1]; + WCHAR pdbfile[MAX_PATH + 1]; + GUID guid; + DWORD sig; + DWORD age; +} SYMSRV_INDEX_INFOW, *PSYMSRV_INDEX_INFOW; + +BOOL +IMAGEAPI +SymSrvGetFileIndexInfo( + __in PCSTR File, + __out PSYMSRV_INDEX_INFO Info, + __in DWORD Flags + ); + +BOOL +IMAGEAPI +SymSrvGetFileIndexInfoW( + __in PCWSTR File, + __out PSYMSRV_INDEX_INFOW Info, + __in DWORD Flags + ); + +PCSTR +IMAGEAPI +SymSrvStoreSupplement( + __in HANDLE hProcess, + __in_opt PCSTR SrvPath, + __in PCSTR Node, + __in PCSTR File, + __in DWORD Flags + ); + +PCWSTR +IMAGEAPI +SymSrvStoreSupplementW( + __in HANDLE hProcess, + __in_opt PCWSTR SymPath, + __in PCWSTR Node, + __in PCWSTR File, + __in DWORD Flags + ); + +PCSTR +IMAGEAPI +SymSrvStoreFile( + __in HANDLE hProcess, + __in_opt PCSTR SrvPath, + __in PCSTR File, + __in DWORD Flags + ); + +PCWSTR +IMAGEAPI +SymSrvStoreFileW( + __in HANDLE hProcess, + __in_opt PCWSTR SrvPath, + __in PCWSTR File, + __in DWORD Flags + ); + +// used by SymGetSymbolFile's "Type" parameter + +typedef enum { + sfImage = 0, + sfDbg, + sfPdb, + sfMpd, + sfMax +} DBG_SF_ENUM; + +BOOL +IMAGEAPI +SymGetSymbolFile( + __in_opt HANDLE hProcess, + __in_opt PCSTR SymPath, + __in PCSTR ImageFile, + __in DWORD Type, + __out_ecount(cSymbolFile) PSTR SymbolFile, + __in size_t cSymbolFile, + __out_ecount(cDbgFile) PSTR DbgFile, + __in size_t cDbgFile + ); + +BOOL +IMAGEAPI +SymGetSymbolFileW( + __in_opt HANDLE hProcess, + __in_opt PCWSTR SymPath, + __in PCWSTR ImageFile, + __in DWORD Type, + __out_ecount(cSymbolFile) PWSTR SymbolFile, + __in size_t cSymbolFile, + __out_ecount(cDbgFile) PWSTR DbgFile, + __in size_t cDbgFile + ); + +// +// Full user-mode dump creation. +// + +typedef BOOL (WINAPI *PDBGHELP_CREATE_USER_DUMP_CALLBACK)( + __in DWORD DataType, + __in PVOID* Data, + __out LPDWORD DataLength, + __in_opt PVOID UserData + ); + +BOOL +WINAPI +DbgHelpCreateUserDump( + __in_opt LPCSTR FileName, + __in PDBGHELP_CREATE_USER_DUMP_CALLBACK Callback, + __in_opt PVOID UserData + ); + +BOOL +WINAPI +DbgHelpCreateUserDumpW( + __in_opt LPCWSTR FileName, + __in PDBGHELP_CREATE_USER_DUMP_CALLBACK Callback, + __in_opt PVOID UserData + ); + +// ----------------------------------------------------------------- +// The following 4 legacy APIs are fully supported, but newer +// ones are recommended. SymFromName and SymFromAddr provide +// much more detailed info on the returned symbol. + +BOOL +IMAGEAPI +SymGetSymFromAddr64( + __in HANDLE hProcess, + __in DWORD64 qwAddr, + __out_opt PDWORD64 pdwDisplacement, + __inout PIMAGEHLP_SYMBOL64 Symbol + ); + + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetSymFromAddr SymGetSymFromAddr64 +#else +BOOL +IMAGEAPI +SymGetSymFromAddr( + __in HANDLE hProcess, + __in DWORD dwAddr, + __out_opt PDWORD pdwDisplacement, + __inout PIMAGEHLP_SYMBOL Symbol + ); +#endif + +// While following two APIs will provide a symbol from a name, +// SymEnumSymbols can provide the same matching information +// for ALL symbols with a matching name, even regular +// expressions. That way you can search across modules +// and differentiate between identically named symbols. + +BOOL +IMAGEAPI +SymGetSymFromName64( + __in HANDLE hProcess, + __in PCSTR Name, + __inout PIMAGEHLP_SYMBOL64 Symbol + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetSymFromName SymGetSymFromName64 +#else +BOOL +IMAGEAPI +SymGetSymFromName( + __in HANDLE hProcess, + __in PCSTR Name, + __inout PIMAGEHLP_SYMBOL Symbol + ); +#endif + + +// Symbol server exports + +typedef BOOL (WINAPI *PSYMBOLSERVERPROC)(PCSTR, PCSTR, PVOID, DWORD, DWORD, PSTR); +typedef BOOL (WINAPI *PSYMBOLSERVERPROCA)(PCSTR, PCSTR, PVOID, DWORD, DWORD, PSTR); +typedef BOOL (WINAPI *PSYMBOLSERVERPROCW)(PCWSTR, PCWSTR, PVOID, DWORD, DWORD, PWSTR); +typedef BOOL (WINAPI *PSYMBOLSERVERBYINDEXPROC)(PCSTR, PCSTR, PCSTR, PSTR); +typedef BOOL (WINAPI *PSYMBOLSERVERBYINDEXPROCA)(PCSTR, PCSTR, PCSTR, PSTR); +typedef BOOL (WINAPI *PSYMBOLSERVERBYINDEXPROCW)(PCWSTR, PCWSTR, PCWSTR, PWSTR); +typedef BOOL (WINAPI *PSYMBOLSERVEROPENPROC)(VOID); +typedef BOOL (WINAPI *PSYMBOLSERVERCLOSEPROC)(VOID); +typedef BOOL (WINAPI *PSYMBOLSERVERSETOPTIONSPROC)(UINT_PTR, ULONG64); +typedef BOOL (WINAPI *PSYMBOLSERVERSETOPTIONSWPROC)(UINT_PTR, ULONG64); +typedef BOOL (CALLBACK WINAPI *PSYMBOLSERVERCALLBACKPROC)(UINT_PTR action, ULONG64 data, ULONG64 context); +typedef UINT_PTR (WINAPI *PSYMBOLSERVERGETOPTIONSPROC)(); +typedef BOOL (WINAPI *PSYMBOLSERVERPINGPROC)(PCSTR); +typedef BOOL (WINAPI *PSYMBOLSERVERPINGPROCA)(PCSTR); +typedef BOOL (WINAPI *PSYMBOLSERVERPINGPROCW)(PCWSTR); +typedef BOOL (WINAPI *PSYMBOLSERVERGETVERSION)(LPAPI_VERSION); +typedef BOOL (WINAPI *PSYMBOLSERVERDELTANAME)(PCSTR, PVOID, DWORD, DWORD, PVOID, DWORD, DWORD, PSTR, size_t); +typedef BOOL (WINAPI *PSYMBOLSERVERDELTANAMEW)(PCWSTR, PVOID, DWORD, DWORD, PVOID, DWORD, DWORD, PWSTR, size_t); +typedef BOOL (WINAPI *PSYMBOLSERVERGETSUPPLEMENT)(PCSTR, PCSTR, PCSTR, PSTR, size_t); +typedef BOOL (WINAPI *PSYMBOLSERVERGETSUPPLEMENTW)(PCWSTR, PCWSTR, PCWSTR, PWSTR, size_t); +typedef BOOL (WINAPI *PSYMBOLSERVERSTORESUPPLEMENT)(PCSTR, PCSTR, PCSTR, PSTR, size_t, DWORD); +typedef BOOL (WINAPI *PSYMBOLSERVERSTORESUPPLEMENTW)(PCWSTR, PCWSTR, PCWSTR, PWSTR, size_t, DWORD); +typedef BOOL (WINAPI *PSYMBOLSERVERGETINDEXSTRING)(PVOID, DWORD, DWORD, PSTR, size_t); +typedef BOOL (WINAPI *PSYMBOLSERVERGETINDEXSTRINGW)(PVOID, DWORD, DWORD, PWSTR, size_t); +typedef BOOL (WINAPI *PSYMBOLSERVERSTOREFILE)(PCSTR, PCSTR, PVOID, DWORD, DWORD, PSTR, size_t, DWORD); +typedef BOOL (WINAPI *PSYMBOLSERVERSTOREFILEW)(PCWSTR, PCWSTR, PVOID, DWORD, DWORD, PWSTR, size_t, DWORD); +typedef BOOL (WINAPI *PSYMBOLSERVERISSTORE)(PCSTR); +typedef BOOL (WINAPI *PSYMBOLSERVERISSTOREW)(PCWSTR); +typedef DWORD (WINAPI *PSYMBOLSERVERVERSION)(); +typedef BOOL (CALLBACK WINAPI *PSYMBOLSERVERMESSAGEPROC)(UINT_PTR action, ULONG64 data, ULONG64 context); + +#define SYMSRV_VERSION 2 + +#define SSRVOPT_CALLBACK 0x00000001 +#define SSRVOPT_DWORD 0x00000002 +#define SSRVOPT_DWORDPTR 0x00000004 +#define SSRVOPT_GUIDPTR 0x00000008 +#define SSRVOPT_OLDGUIDPTR 0x00000010 +#define SSRVOPT_UNATTENDED 0x00000020 +#define SSRVOPT_NOCOPY 0x00000040 +#define SSRVOPT_GETPATH 0x00000040 +#define SSRVOPT_PARENTWIN 0x00000080 +#define SSRVOPT_PARAMTYPE 0x00000100 +#define SSRVOPT_SECURE 0x00000200 +#define SSRVOPT_TRACE 0x00000400 +#define SSRVOPT_SETCONTEXT 0x00000800 +#define SSRVOPT_PROXY 0x00001000 +#define SSRVOPT_DOWNSTREAM_STORE 0x00002000 +#define SSRVOPT_OVERWRITE 0x00004000 +#define SSRVOPT_RESETTOU 0x00008000 +#define SSRVOPT_CALLBACKW 0x00010000 +#define SSRVOPT_FLAT_DEFAULT_STORE 0x00020000 +#define SSRVOPT_PROXYW 0x00040000 +#define SSRVOPT_MESSAGE 0x00080000 +#define SSRVOPT_SERVICE 0x00100000 // deprecated +#define SSRVOPT_FAVOR_COMPRESSED 0x00200000 +#define SSRVOPT_STRING 0x00400000 +#define SSRVOPT_WINHTTP 0x00800000 +#define SSRVOPT_WININET 0x01000000 + +#define SSRVOPT_MAX 0x0100000 + +#define SSRVOPT_RESET ((ULONG_PTR)-1) + + +#define NUM_SSRVOPTS 30 + +#define SSRVACTION_TRACE 1 +#define SSRVACTION_QUERYCANCEL 2 +#define SSRVACTION_EVENT 3 +#define SSRVACTION_EVENTW 4 +#define SSRVACTION_SIZE 5 + +#define SYMSTOREOPT_COMPRESS 0x01 +#define SYMSTOREOPT_OVERWRITE 0x02 +#define SYMSTOREOPT_RETURNINDEX 0x04 +#define SYMSTOREOPT_POINTER 0x08 +#define SYMSTOREOPT_ALT_INDEX 0x10 +#define SYMSTOREOPT_UNICODE 0x20 +#define SYMSTOREOPT_PASS_IF_EXISTS 0x40 + +#ifdef DBGHELP_TRANSLATE_TCHAR + #define SymInitialize SymInitializeW + #define SymAddSymbol SymAddSymbolW + #define SymDeleteSymbol SymDeleteSymbolW + #define SearchTreeForFile SearchTreeForFileW + #define UnDecorateSymbolName UnDecorateSymbolNameW + #define SymGetLineFromName64 SymGetLineFromNameW64 + #define SymGetLineFromAddr64 SymGetLineFromAddrW64 + #define SymGetLineNext64 SymGetLineNextW64 + #define SymGetLinePrev64 SymGetLinePrevW64 + #define SymFromName SymFromNameW + #define SymFindExecutableImage SymFindExecutableImageW + #define FindExecutableImageEx FindExecutableImageExW + #define SymSearch SymSearchW + #define SymEnumLines SymEnumLinesW + #define SymEnumSourceLines SymEnumSourceLinesW + #define SymGetTypeFromName SymGetTypeFromNameW + #define SymEnumSymbolsForAddr SymEnumSymbolsForAddrW + #define SymFromAddr SymFromAddrW + #define SymMatchString SymMatchStringW + #define SymEnumSourceFiles SymEnumSourceFilesW + #define SymEnumSymbols SymEnumSymbolsW + #define SymLoadModuleEx SymLoadModuleExW + #define SymSetSearchPath SymSetSearchPathW + #define SymGetSearchPath SymGetSearchPathW + #define EnumDirTree EnumDirTreeW + #define SymFromToken SymFromTokenW + #define SymFromIndex SymFromIndexW + #define SymGetScope SymGetScopeW + #define SymNext SymNextW + #define SymPrev SymPrevW + #define SymEnumTypes SymEnumTypesW + #define SymEnumTypesByName SymEnumTypesByNameW + #define SymRegisterCallback64 SymRegisterCallbackW64 + #define SymFindDebugInfoFile SymFindDebugInfoFileW + #define FindDebugInfoFileEx FindDebugInfoFileExW + #define SymFindFileInPath SymFindFileInPathW + #define SymEnumerateModules64 SymEnumerateModulesW64 + #define SymSetHomeDirectory SymSetHomeDirectoryW + #define SymGetHomeDirectory SymGetHomeDirectoryW + #define SymGetSourceFile SymGetSourceFileW + #define SymGetSourceFileToken SymGetSourceFileTokenW + #define SymGetSourceFileFromToken SymGetSourceFileFromTokenW + #define SymGetSourceVarFromToken SymGetSourceVarFromTokenW + #define SymGetSourceFileToken SymGetSourceFileTokenW + #define SymGetFileLineOffsets64 SymGetFileLineOffsetsW64 + #define SymFindFileInPath SymFindFileInPathW + #define SymMatchFileName SymMatchFileNameW + #define SymGetSourceFileFromToken SymGetSourceFileFromTokenW + #define SymGetSourceVarFromToken SymGetSourceVarFromTokenW + #define SymGetModuleInfo64 SymGetModuleInfoW64 + #define SymSrvIsStore SymSrvIsStoreW + #define SymSrvDeltaName SymSrvDeltaNameW + #define SymSrvGetSupplement SymSrvGetSupplementW + #define SymSrvStoreSupplement SymSrvStoreSupplementW + #define SymSrvGetFileIndexes SymSrvGetFileIndexes + #define SymSrvGetFileIndexString SymSrvGetFileIndexStringW + #define SymSrvStoreFile SymSrvStoreFileW + #define SymGetSymbolFile SymGetSymbolFileW + #define EnumerateLoadedModules64 EnumerateLoadedModulesW64 + #define EnumerateLoadedModulesEx EnumerateLoadedModulesExW + #define SymSrvGetFileIndexInfo SymSrvGetFileIndexInfoW + + #define IMAGEHLP_LINE64 IMAGEHLP_LINEW64 + #define PIMAGEHLP_LINE64 PIMAGEHLP_LINEW64 + #define SYMBOL_INFO SYMBOL_INFOW + #define PSYMBOL_INFO PSYMBOL_INFOW + #define SYMBOL_INFO_PACKAGE SYMBOL_INFO_PACKAGEW + #define PSYMBOL_INFO_PACKAGE PSYMBOL_INFO_PACKAGEW + #define FIND_EXE_FILE_CALLBACK FIND_EXE_FILE_CALLBACKW + #define PFIND_EXE_FILE_CALLBACK PFIND_EXE_FILE_CALLBACKW + #define SYM_ENUMERATESYMBOLS_CALLBACK SYM_ENUMERATESYMBOLS_CALLBACKW + #define PSYM_ENUMERATESYMBOLS_CALLBACK PSYM_ENUMERATESYMBOLS_CALLBACKW + #define SRCCODEINFO SRCCODEINFOW + #define PSRCCODEINFO PSRCCODEINFOW + #define SOURCEFILE SOURCEFILEW + #define PSOURCEFILE PSOURCEFILEW + #define SYM_ENUMSOURECFILES_CALLBACK SYM_ENUMSOURCEFILES_CALLBACKW + #define PSYM_ENUMSOURCEFILES_CALLBACK PSYM_ENUMSOURECFILES_CALLBACKW + #define IMAGEHLP_CBA_EVENT IMAGEHLP_CBA_EVENTW + #define PIMAGEHLP_CBA_EVENT PIMAGEHLP_CBA_EVENTW + #define PENUMDIRTREE_CALLBACK PENUMDIRTREE_CALLBACKW + #define IMAGEHLP_DEFERRED_SYMBOL_LOAD64 IMAGEHLP_DEFERRED_SYMBOL_LOADW64 + #define PIMAGEHLP_DEFERRED_SYMBOL_LOAD64 PIMAGEHLP_DEFERRED_SYMBOL_LOADW64 + #define PFIND_DEBUG_FILE_CALLBACK PFIND_DEBUG_FILE_CALLBACKW + #define PFINDFILEINPATHCALLBACK PFINDFILEINPATHCALLBACKW + #define IMAGEHLP_MODULE64 IMAGEHLP_MODULEW64 + #define PIMAGEHLP_MODULE64 PIMAGEHLP_MODULEW64 + #define SYMSRV_INDEX_INFO SYMSRV_INDEX_INFOW + #define PSYMSRV_INDEX_INFO PSYMSRV_INDEX_INFOW + + #define PSYMBOLSERVERPROC PSYMBOLSERVERPROCW + #define PSYMBOLSERVERPINGPROC PSYMBOLSERVERPINGPROCW +#endif + +// ----------------------------------------------------------------- +// The following APIs exist only for backwards compatibility +// with a pre-release version documented in an MSDN release. + +// You should use SymFindFileInPath if you want to maintain +// future compatibility. + +DBHLP_DEPRECIATED +BOOL +IMAGEAPI +FindFileInPath( + __in HANDLE hprocess, + __in PCSTR SearchPath, + __in PCSTR FileName, + __in PVOID id, + __in DWORD two, + __in DWORD three, + __in DWORD flags, + __out_ecount(MAX_PATH + 1) PSTR FilePath + ); + +// You should use SymFindFileInPath if you want to maintain +// future compatibility. + +DBHLP_DEPRECIATED +BOOL +IMAGEAPI +FindFileInSearchPath( + __in HANDLE hprocess, + __in PCSTR SearchPath, + __in PCSTR FileName, + __in DWORD one, + __in DWORD two, + __in DWORD three, + __out_ecount(MAX_PATH + 1) PSTR FilePath + ); + +DBHLP_DEPRECIATED +BOOL +IMAGEAPI +SymEnumSym( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback, + __in_opt PVOID UserContext + ); + +DBHLP_DEPRECIATED +BOOL +IMAGEAPI +SymEnumerateSymbols64( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PSYM_ENUMSYMBOLS_CALLBACK64 EnumSymbolsCallback, + __in_opt PVOID UserContext + ); + +DBHLP_DEPRECIATED +BOOL +IMAGEAPI +SymEnumerateSymbolsW64( + __in HANDLE hProcess, + __in ULONG64 BaseOfDll, + __in PSYM_ENUMSYMBOLS_CALLBACK64W EnumSymbolsCallback, + __in_opt PVOID UserContext + ); + + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymEnumerateSymbols SymEnumerateSymbols64 +#define SymEnumerateSymbolsW SymEnumerateSymbolsW64 +#else +DBHLP_DEPRECIATED +BOOL +IMAGEAPI +SymEnumerateSymbols( + __in HANDLE hProcess, + __in ULONG BaseOfDll, + __in PSYM_ENUMSYMBOLS_CALLBACK EnumSymbolsCallback, + __in_opt PVOID UserContext + ); + +DBHLP_DEPRECIATED +BOOL +IMAGEAPI +SymEnumerateSymbolsW( + __in HANDLE hProcess, + __in ULONG BaseOfDll, + __in PSYM_ENUMSYMBOLS_CALLBACKW EnumSymbolsCallback, + __in_opt PVOID UserContext + ); +#endif + +// use SymLoadModuleEx + +DWORD64 +IMAGEAPI +SymLoadModule64( + __in HANDLE hProcess, + __in_opt HANDLE hFile, + __in_opt PCSTR ImageName, + __in_opt PCSTR ModuleName, + __in DWORD64 BaseOfDll, + __in DWORD SizeOfDll + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymLoadModule SymLoadModule64 +#else +DWORD +IMAGEAPI +SymLoadModule( + __in HANDLE hProcess, + __in_opt HANDLE hFile, + __in_opt PCSTR ImageName, + __in_opt PCSTR ModuleName, + __in DWORD BaseOfDll, + __in DWORD SizeOfDll + ); +#endif + +BOOL +IMAGEAPI +SymGetSymNext64( + __in HANDLE hProcess, + __inout PIMAGEHLP_SYMBOL64 Symbol + ); + +BOOL +IMAGEAPI +SymGetSymNextW64( + __in HANDLE hProcess, + __inout PIMAGEHLP_SYMBOLW64 Symbol + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetSymNext SymGetSymNext64 +#define SymGetSymNextW SymGetSymNextW64 +#else +BOOL +IMAGEAPI +SymGetSymNext( + __in HANDLE hProcess, + __inout PIMAGEHLP_SYMBOL Symbol + ); + +BOOL +IMAGEAPI +SymGetSymNextW( + __in HANDLE hProcess, + __inout PIMAGEHLP_SYMBOLW Symbol + ); +#endif + +BOOL +IMAGEAPI +SymGetSymPrev64( + __in HANDLE hProcess, + __inout PIMAGEHLP_SYMBOL64 Symbol + ); + +BOOL +IMAGEAPI +SymGetSymPrevW64( + __in HANDLE hProcess, + __inout PIMAGEHLP_SYMBOLW64 Symbol + ); + +#if !defined(_IMAGEHLP_SOURCE_) && defined(_IMAGEHLP64) +#define SymGetSymPrev SymGetSymPrev64 +#define SymGetSymPrevW SymGetSymPrevW64 +#else +BOOL +IMAGEAPI +SymGetSymPrev( + __in HANDLE hProcess, + __inout PIMAGEHLP_SYMBOL Symbol + ); + +BOOL +IMAGEAPI +SymGetSymPrevW( + __in HANDLE hProcess, + __inout PIMAGEHLP_SYMBOLW Symbol + ); +#endif + + +// These values should not be used. +// They have been replaced by SYMFLAG_ values. + +#define SYMF_OMAP_GENERATED 0x00000001 +#define SYMF_OMAP_MODIFIED 0x00000002 +#define SYMF_REGISTER 0x00000008 +#define SYMF_REGREL 0x00000010 +#define SYMF_FRAMEREL 0x00000020 +#define SYMF_PARAMETER 0x00000040 +#define SYMF_LOCAL 0x00000080 +#define SYMF_CONSTANT 0x00000100 +#define SYMF_EXPORT 0x00000200 +#define SYMF_FORWARDER 0x00000400 +#define SYMF_FUNCTION 0x00000800 +#define SYMF_VIRTUAL 0x00001000 +#define SYMF_THUNK 0x00002000 +#define SYMF_TLSREL 0x00004000 + +// These values should also not be used. +// They have been replaced by SYMFLAG_ values. + +#define IMAGEHLP_SYMBOL_INFO_VALUEPRESENT 1 +#define IMAGEHLP_SYMBOL_INFO_REGISTER SYMF_REGISTER // 0x0008 +#define IMAGEHLP_SYMBOL_INFO_REGRELATIVE SYMF_REGREL // 0x0010 +#define IMAGEHLP_SYMBOL_INFO_FRAMERELATIVE SYMF_FRAMEREL // 0x0020 +#define IMAGEHLP_SYMBOL_INFO_PARAMETER SYMF_PARAMETER // 0x0040 +#define IMAGEHLP_SYMBOL_INFO_LOCAL SYMF_LOCAL // 0x0080 +#define IMAGEHLP_SYMBOL_INFO_CONSTANT SYMF_CONSTANT // 0x0100 +#define IMAGEHLP_SYMBOL_FUNCTION SYMF_FUNCTION // 0x0800 +#define IMAGEHLP_SYMBOL_VIRTUAL SYMF_VIRTUAL // 0x1000 +#define IMAGEHLP_SYMBOL_THUNK SYMF_THUNK // 0x2000 +#define IMAGEHLP_SYMBOL_INFO_TLSRELATIVE SYMF_TLSREL // 0x4000 + +#include + + +#include + +#if defined(_MSC_VER) +#if _MSC_VER >= 800 +#if _MSC_VER >= 1200 +#pragma warning(push) +#endif +#pragma warning(disable:4200) /* Zero length array */ +#pragma warning(disable:4201) /* Nameless struct/union */ +#endif +#endif + +#define MINIDUMP_SIGNATURE ('PMDM') +#define MINIDUMP_VERSION (42899) +typedef DWORD RVA; +typedef ULONG64 RVA64; + +typedef struct _MINIDUMP_LOCATION_DESCRIPTOR { + ULONG32 DataSize; + RVA Rva; +} MINIDUMP_LOCATION_DESCRIPTOR; + +typedef struct _MINIDUMP_LOCATION_DESCRIPTOR64 { + ULONG64 DataSize; + RVA64 Rva; +} MINIDUMP_LOCATION_DESCRIPTOR64; + + +typedef struct _MINIDUMP_MEMORY_DESCRIPTOR { + ULONG64 StartOfMemoryRange; + MINIDUMP_LOCATION_DESCRIPTOR Memory; +} MINIDUMP_MEMORY_DESCRIPTOR, *PMINIDUMP_MEMORY_DESCRIPTOR; + +// DESCRIPTOR64 is used for full-memory minidumps where +// all of the raw memory is laid out sequentially at the +// end of the dump. There is no need for individual RVAs +// as the RVA is the base RVA plus the sum of the preceeding +// data blocks. +typedef struct _MINIDUMP_MEMORY_DESCRIPTOR64 { + ULONG64 StartOfMemoryRange; + ULONG64 DataSize; +} MINIDUMP_MEMORY_DESCRIPTOR64, *PMINIDUMP_MEMORY_DESCRIPTOR64; + + +typedef struct _MINIDUMP_HEADER { + ULONG32 Signature; + ULONG32 Version; + ULONG32 NumberOfStreams; + RVA StreamDirectoryRva; + ULONG32 CheckSum; + union { + ULONG32 Reserved; + ULONG32 TimeDateStamp; + }; + ULONG64 Flags; +} MINIDUMP_HEADER, *PMINIDUMP_HEADER; + +// +// The MINIDUMP_HEADER field StreamDirectoryRva points to +// an array of MINIDUMP_DIRECTORY structures. +// + +typedef struct _MINIDUMP_DIRECTORY { + ULONG32 StreamType; + MINIDUMP_LOCATION_DESCRIPTOR Location; +} MINIDUMP_DIRECTORY, *PMINIDUMP_DIRECTORY; + + +typedef struct _MINIDUMP_STRING { + ULONG32 Length; // Length in bytes of the string + WCHAR Buffer [0]; // Variable size buffer +} MINIDUMP_STRING, *PMINIDUMP_STRING; + + + +// +// The MINIDUMP_DIRECTORY field StreamType may be one of the following types. +// Types will be added in the future, so if a program reading the minidump +// header encounters a stream type it does not understand it should ignore +// the data altogether. Any tag above LastReservedStream will not be used by +// the system and is reserved for program-specific information. +// + +typedef enum _MINIDUMP_STREAM_TYPE { + + UnusedStream = 0, + ReservedStream0 = 1, + ReservedStream1 = 2, + ThreadListStream = 3, + ModuleListStream = 4, + MemoryListStream = 5, + ExceptionStream = 6, + SystemInfoStream = 7, + ThreadExListStream = 8, + Memory64ListStream = 9, + CommentStreamA = 10, + CommentStreamW = 11, + HandleDataStream = 12, + FunctionTableStream = 13, + UnloadedModuleListStream = 14, + MiscInfoStream = 15, + MemoryInfoListStream = 16, + ThreadInfoListStream = 17, + HandleOperationListStream = 18, + TokenStream = 19, + + ceStreamNull = 0x8000, + ceStreamSystemInfo = 0x8001, + ceStreamException = 0x8002, + ceStreamModuleList = 0x8003, + ceStreamProcessList = 0x8004, + ceStreamThreadList = 0x8005, + ceStreamThreadContextList = 0x8006, + ceStreamThreadCallStackList = 0x8007, + ceStreamMemoryVirtualList = 0x8008, + ceStreamMemoryPhysicalList = 0x8009, + ceStreamBucketParameters = 0x800A, + ceStreamProcessModuleMap = 0x800B, + ceStreamDiagnosisList = 0x800C, + + LastReservedStream = 0xffff + +} MINIDUMP_STREAM_TYPE; + + +// +// The minidump system information contains processor and +// Operating System specific information. +// + +// +// CPU information is obtained from one of two places. +// +// 1) On x86 computers, CPU_INFORMATION is obtained from the CPUID +// instruction. You must use the X86 portion of the union for X86 +// computers. +// +// 2) On non-x86 architectures, CPU_INFORMATION is obtained by calling +// IsProcessorFeatureSupported(). +// + +typedef union _CPU_INFORMATION { + + // + // X86 platforms use CPUID function to obtain processor information. + // + + struct { + + // + // CPUID Subfunction 0, register EAX (VendorId [0]), + // EBX (VendorId [1]) and ECX (VendorId [2]). + // + + ULONG32 VendorId [ 3 ]; + + // + // CPUID Subfunction 1, register EAX + // + + ULONG32 VersionInformation; + + // + // CPUID Subfunction 1, register EDX + // + + ULONG32 FeatureInformation; + + + // + // CPUID, Subfunction 80000001, register EBX. This will only + // be obtained if the vendor id is "AuthenticAMD". + // + + ULONG32 AMDExtendedCpuFeatures; + + } X86CpuInfo; + + // + // Non-x86 platforms use processor feature flags. + // + + struct { + + ULONG64 ProcessorFeatures [ 2 ]; + + } OtherCpuInfo; + +} CPU_INFORMATION, *PCPU_INFORMATION; + +typedef struct _MINIDUMP_SYSTEM_INFO { + + // + // ProcessorArchitecture, ProcessorLevel and ProcessorRevision are all + // taken from the SYSTEM_INFO structure obtained by GetSystemInfo( ). + // + + USHORT ProcessorArchitecture; + USHORT ProcessorLevel; + USHORT ProcessorRevision; + + union { + USHORT Reserved0; + struct { + UCHAR NumberOfProcessors; + UCHAR ProductType; + }; + }; + + // + // MajorVersion, MinorVersion, BuildNumber, PlatformId and + // CSDVersion are all taken from the OSVERSIONINFO structure + // returned by GetVersionEx( ). + // + + ULONG32 MajorVersion; + ULONG32 MinorVersion; + ULONG32 BuildNumber; + ULONG32 PlatformId; + + // + // RVA to a CSDVersion string in the string table. + // + + RVA CSDVersionRva; + + union { + ULONG32 Reserved1; + struct { + USHORT SuiteMask; + USHORT Reserved2; + }; + }; + + CPU_INFORMATION Cpu; + +} MINIDUMP_SYSTEM_INFO, *PMINIDUMP_SYSTEM_INFO; + + +// +// The minidump thread contains standard thread +// information plus an RVA to the memory for this +// thread and an RVA to the CONTEXT structure for +// this thread. +// + + +// +// ThreadId must be 4 bytes on all architectures. +// + +C_ASSERT (sizeof ( ((PPROCESS_INFORMATION)0)->dwThreadId ) == 4); + +typedef struct _MINIDUMP_THREAD { + ULONG32 ThreadId; + ULONG32 SuspendCount; + ULONG32 PriorityClass; + ULONG32 Priority; + ULONG64 Teb; + MINIDUMP_MEMORY_DESCRIPTOR Stack; + MINIDUMP_LOCATION_DESCRIPTOR ThreadContext; +} MINIDUMP_THREAD, *PMINIDUMP_THREAD; + +// +// The thread list is a container of threads. +// + +typedef struct _MINIDUMP_THREAD_LIST { + ULONG32 NumberOfThreads; + MINIDUMP_THREAD Threads [0]; +} MINIDUMP_THREAD_LIST, *PMINIDUMP_THREAD_LIST; + + +typedef struct _MINIDUMP_THREAD_EX { + ULONG32 ThreadId; + ULONG32 SuspendCount; + ULONG32 PriorityClass; + ULONG32 Priority; + ULONG64 Teb; + MINIDUMP_MEMORY_DESCRIPTOR Stack; + MINIDUMP_LOCATION_DESCRIPTOR ThreadContext; + MINIDUMP_MEMORY_DESCRIPTOR BackingStore; +} MINIDUMP_THREAD_EX, *PMINIDUMP_THREAD_EX; + +// +// The thread list is a container of threads. +// + +typedef struct _MINIDUMP_THREAD_EX_LIST { + ULONG32 NumberOfThreads; + MINIDUMP_THREAD_EX Threads [0]; +} MINIDUMP_THREAD_EX_LIST, *PMINIDUMP_THREAD_EX_LIST; + + +// +// The MINIDUMP_EXCEPTION is the same as EXCEPTION on Win64. +// + +typedef struct _MINIDUMP_EXCEPTION { + ULONG32 ExceptionCode; + ULONG32 ExceptionFlags; + ULONG64 ExceptionRecord; + ULONG64 ExceptionAddress; + ULONG32 NumberParameters; + ULONG32 __unusedAlignment; + ULONG64 ExceptionInformation [ EXCEPTION_MAXIMUM_PARAMETERS ]; +} MINIDUMP_EXCEPTION, *PMINIDUMP_EXCEPTION; + + +// +// The exception information stream contains the id of the thread that caused +// the exception (ThreadId), the exception record for the exception +// (ExceptionRecord) and an RVA to the thread context where the exception +// occured. +// + +typedef struct MINIDUMP_EXCEPTION_STREAM { + ULONG32 ThreadId; + ULONG32 __alignment; + MINIDUMP_EXCEPTION ExceptionRecord; + MINIDUMP_LOCATION_DESCRIPTOR ThreadContext; +} MINIDUMP_EXCEPTION_STREAM, *PMINIDUMP_EXCEPTION_STREAM; + + +// +// The MINIDUMP_MODULE contains information about a +// a specific module. It includes the CheckSum and +// the TimeDateStamp for the module so the module +// can be reloaded during the analysis phase. +// + +typedef struct _MINIDUMP_MODULE { + ULONG64 BaseOfImage; + ULONG32 SizeOfImage; + ULONG32 CheckSum; + ULONG32 TimeDateStamp; + RVA ModuleNameRva; + VS_FIXEDFILEINFO VersionInfo; + MINIDUMP_LOCATION_DESCRIPTOR CvRecord; + MINIDUMP_LOCATION_DESCRIPTOR MiscRecord; + ULONG64 Reserved0; // Reserved for future use. + ULONG64 Reserved1; // Reserved for future use. +} MINIDUMP_MODULE, *PMINIDUMP_MODULE; + + +// +// The minidump module list is a container for modules. +// + +typedef struct _MINIDUMP_MODULE_LIST { + ULONG32 NumberOfModules; + MINIDUMP_MODULE Modules [ 0 ]; +} MINIDUMP_MODULE_LIST, *PMINIDUMP_MODULE_LIST; + + +// +// Memory Ranges +// + +typedef struct _MINIDUMP_MEMORY_LIST { + ULONG32 NumberOfMemoryRanges; + MINIDUMP_MEMORY_DESCRIPTOR MemoryRanges [0]; +} MINIDUMP_MEMORY_LIST, *PMINIDUMP_MEMORY_LIST; + +typedef struct _MINIDUMP_MEMORY64_LIST { + ULONG64 NumberOfMemoryRanges; + RVA64 BaseRva; + MINIDUMP_MEMORY_DESCRIPTOR64 MemoryRanges [0]; +} MINIDUMP_MEMORY64_LIST, *PMINIDUMP_MEMORY64_LIST; + + +// +// Support for user supplied exception information. +// + +typedef struct _MINIDUMP_EXCEPTION_INFORMATION { + DWORD ThreadId; + PEXCEPTION_POINTERS ExceptionPointers; + BOOL ClientPointers; +} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION; + +typedef struct _MINIDUMP_EXCEPTION_INFORMATION64 { + DWORD ThreadId; + ULONG64 ExceptionRecord; + ULONG64 ContextRecord; + BOOL ClientPointers; +} MINIDUMP_EXCEPTION_INFORMATION64, *PMINIDUMP_EXCEPTION_INFORMATION64; + + +// +// Support for capturing system handle state at the time of the dump. +// + +// Per-handle object information varies according to +// the OS, the OS version, the processor type and +// so on. The minidump gives a minidump identifier +// to each possible data format for identification +// purposes but does not control nor describe the actual data. +typedef enum _MINIDUMP_HANDLE_OBJECT_INFORMATION_TYPE { + MiniHandleObjectInformationNone, + MiniThreadInformation1, + MiniMutantInformation1, + MiniMutantInformation2, + MiniProcessInformation1, + MiniProcessInformation2, + MiniHandleObjectInformationTypeMax +} MINIDUMP_HANDLE_OBJECT_INFORMATION_TYPE; + +typedef struct _MINIDUMP_HANDLE_OBJECT_INFORMATION { + RVA NextInfoRva; + ULONG32 InfoType; + ULONG32 SizeOfInfo; + // Raw information follows. +} MINIDUMP_HANDLE_OBJECT_INFORMATION; + +typedef struct _MINIDUMP_HANDLE_DESCRIPTOR { + ULONG64 Handle; + RVA TypeNameRva; + RVA ObjectNameRva; + ULONG32 Attributes; + ULONG32 GrantedAccess; + ULONG32 HandleCount; + ULONG32 PointerCount; +} MINIDUMP_HANDLE_DESCRIPTOR, *PMINIDUMP_HANDLE_DESCRIPTOR; + +typedef struct _MINIDUMP_HANDLE_DESCRIPTOR_2 { + ULONG64 Handle; + RVA TypeNameRva; + RVA ObjectNameRva; + ULONG32 Attributes; + ULONG32 GrantedAccess; + ULONG32 HandleCount; + ULONG32 PointerCount; + RVA ObjectInfoRva; + ULONG32 Reserved0; +} MINIDUMP_HANDLE_DESCRIPTOR_2, *PMINIDUMP_HANDLE_DESCRIPTOR_2; + +// The latest MINIDUMP_HANDLE_DESCRIPTOR definition. +typedef MINIDUMP_HANDLE_DESCRIPTOR_2 MINIDUMP_HANDLE_DESCRIPTOR_N; +typedef MINIDUMP_HANDLE_DESCRIPTOR_N *PMINIDUMP_HANDLE_DESCRIPTOR_N; + +typedef struct _MINIDUMP_HANDLE_DATA_STREAM { + ULONG32 SizeOfHeader; + ULONG32 SizeOfDescriptor; + ULONG32 NumberOfDescriptors; + ULONG32 Reserved; +} MINIDUMP_HANDLE_DATA_STREAM, *PMINIDUMP_HANDLE_DATA_STREAM; + +// Some operating systems can track the last operations +// performed on a handle. For example, Application Verifier +// can enable this for some versions of Windows. The +// handle operation list collects handle operations +// known for the dump target. +// Each entry is an AVRF_HANDLE_OPERATION. +typedef struct _MINIDUMP_HANDLE_OPERATION_LIST { + ULONG32 SizeOfHeader; + ULONG32 SizeOfEntry; + ULONG32 NumberOfEntries; + ULONG32 Reserved; +} MINIDUMP_HANDLE_OPERATION_LIST, *PMINIDUMP_HANDLE_OPERATION_LIST; + + +// +// Support for capturing dynamic function table state at the time of the dump. +// + +typedef struct _MINIDUMP_FUNCTION_TABLE_DESCRIPTOR { + ULONG64 MinimumAddress; + ULONG64 MaximumAddress; + ULONG64 BaseAddress; + ULONG32 EntryCount; + ULONG32 SizeOfAlignPad; +} MINIDUMP_FUNCTION_TABLE_DESCRIPTOR, *PMINIDUMP_FUNCTION_TABLE_DESCRIPTOR; + +typedef struct _MINIDUMP_FUNCTION_TABLE_STREAM { + ULONG32 SizeOfHeader; + ULONG32 SizeOfDescriptor; + ULONG32 SizeOfNativeDescriptor; + ULONG32 SizeOfFunctionEntry; + ULONG32 NumberOfDescriptors; + ULONG32 SizeOfAlignPad; +} MINIDUMP_FUNCTION_TABLE_STREAM, *PMINIDUMP_FUNCTION_TABLE_STREAM; + + +// +// The MINIDUMP_UNLOADED_MODULE contains information about a +// a specific module that was previously loaded but no +// longer is. This can help with diagnosing problems where +// callers attempt to call code that is no longer loaded. +// + +typedef struct _MINIDUMP_UNLOADED_MODULE { + ULONG64 BaseOfImage; + ULONG32 SizeOfImage; + ULONG32 CheckSum; + ULONG32 TimeDateStamp; + RVA ModuleNameRva; +} MINIDUMP_UNLOADED_MODULE, *PMINIDUMP_UNLOADED_MODULE; + + +// +// The minidump unloaded module list is a container for unloaded modules. +// + +typedef struct _MINIDUMP_UNLOADED_MODULE_LIST { + ULONG32 SizeOfHeader; + ULONG32 SizeOfEntry; + ULONG32 NumberOfEntries; +} MINIDUMP_UNLOADED_MODULE_LIST, *PMINIDUMP_UNLOADED_MODULE_LIST; + + +// +// The miscellaneous information stream contains a variety +// of small pieces of information. A member is valid if +// it's within the available size and its corresponding +// bit is set. +// + +#define MINIDUMP_MISC1_PROCESS_ID 0x00000001 +#define MINIDUMP_MISC1_PROCESS_TIMES 0x00000002 +#define MINIDUMP_MISC1_PROCESSOR_POWER_INFO 0x00000004 +#define MINIDUMP_MISC3_PROCESS_INTEGRITY 0x00000010 +#define MINIDUMP_MISC3_PROCESS_EXECUTE_FLAGS 0x00000020 +#define MINIDUMP_MISC3_TIMEZONE 0x00000040 +#define MINIDUMP_MISC3_PROTECTED_PROCESS 0x00000080 + +typedef struct _MINIDUMP_MISC_INFO { + ULONG32 SizeOfInfo; + ULONG32 Flags1; + ULONG32 ProcessId; + ULONG32 ProcessCreateTime; + ULONG32 ProcessUserTime; + ULONG32 ProcessKernelTime; +} MINIDUMP_MISC_INFO, *PMINIDUMP_MISC_INFO; + +typedef struct _MINIDUMP_MISC_INFO_2 { + ULONG32 SizeOfInfo; + ULONG32 Flags1; + ULONG32 ProcessId; + ULONG32 ProcessCreateTime; + ULONG32 ProcessUserTime; + ULONG32 ProcessKernelTime; + ULONG32 ProcessorMaxMhz; + ULONG32 ProcessorCurrentMhz; + ULONG32 ProcessorMhzLimit; + ULONG32 ProcessorMaxIdleState; + ULONG32 ProcessorCurrentIdleState; +} MINIDUMP_MISC_INFO_2, *PMINIDUMP_MISC_INFO_2; + +typedef struct _MINIDUMP_MISC_INFO_3 { + ULONG32 SizeOfInfo; + ULONG32 Flags1; + ULONG32 ProcessId; + ULONG32 ProcessCreateTime; + ULONG32 ProcessUserTime; + ULONG32 ProcessKernelTime; + ULONG32 ProcessorMaxMhz; + ULONG32 ProcessorCurrentMhz; + ULONG32 ProcessorMhzLimit; + ULONG32 ProcessorMaxIdleState; + ULONG32 ProcessorCurrentIdleState; + ULONG32 ProcessIntegrityLevel; + ULONG32 ProcessExecuteFlags; + ULONG32 ProtectedProcess; + ULONG32 TimeZoneId; + TIME_ZONE_INFORMATION TimeZone; +} MINIDUMP_MISC_INFO_3, *PMINIDUMP_MISC_INFO_3; + +// The latest MINIDUMP_MISC_INFO definition. +typedef MINIDUMP_MISC_INFO_3 MINIDUMP_MISC_INFO_N; +typedef MINIDUMP_MISC_INFO_N* PMINIDUMP_MISC_INFO_N; + + +// +// The memory information stream contains memory region +// description information. This stream corresponds to +// what VirtualQuery would return for the process the +// dump was created for. +// + +typedef struct _MINIDUMP_MEMORY_INFO { + ULONG64 BaseAddress; + ULONG64 AllocationBase; + ULONG32 AllocationProtect; + ULONG32 __alignment1; + ULONG64 RegionSize; + ULONG32 State; + ULONG32 Protect; + ULONG32 Type; + ULONG32 __alignment2; +} MINIDUMP_MEMORY_INFO, *PMINIDUMP_MEMORY_INFO; + +typedef struct _MINIDUMP_MEMORY_INFO_LIST { + ULONG SizeOfHeader; + ULONG SizeOfEntry; + ULONG64 NumberOfEntries; +} MINIDUMP_MEMORY_INFO_LIST, *PMINIDUMP_MEMORY_INFO_LIST; + + +// +// The memory information stream contains memory region +// description information. This stream corresponds to +// what VirtualQuery would return for the process the +// dump was created for. +// + +// Thread dump writer status flags. +#define MINIDUMP_THREAD_INFO_ERROR_THREAD 0x00000001 +#define MINIDUMP_THREAD_INFO_WRITING_THREAD 0x00000002 +#define MINIDUMP_THREAD_INFO_EXITED_THREAD 0x00000004 +#define MINIDUMP_THREAD_INFO_INVALID_INFO 0x00000008 +#define MINIDUMP_THREAD_INFO_INVALID_CONTEXT 0x00000010 +#define MINIDUMP_THREAD_INFO_INVALID_TEB 0x00000020 + +typedef struct _MINIDUMP_THREAD_INFO { + ULONG32 ThreadId; + ULONG32 DumpFlags; + ULONG32 DumpError; + ULONG32 ExitStatus; + ULONG64 CreateTime; + ULONG64 ExitTime; + ULONG64 KernelTime; + ULONG64 UserTime; + ULONG64 StartAddress; + ULONG64 Affinity; +} MINIDUMP_THREAD_INFO, *PMINIDUMP_THREAD_INFO; + +typedef struct _MINIDUMP_THREAD_INFO_LIST { + ULONG SizeOfHeader; + ULONG SizeOfEntry; + ULONG NumberOfEntries; +} MINIDUMP_THREAD_INFO_LIST, *PMINIDUMP_THREAD_INFO_LIST; + +// +// Support for token information. +// +typedef struct _MINIDUMP_TOKEN_INFO_HEADER { + ULONG TokenSize; // The size of the token structure. + ULONG TokenId; // The PID in NtOpenProcessToken() call or TID in NtOpenThreadToken() call. + ULONG64 TokenHandle; // The handle value returned. +} MINIDUMP_TOKEN_INFO_HEADER, *PMINIDUMP_TOKEN_INFO_HEADER; + +typedef struct _MINIDUMP_TOKEN_INFO_LIST { + ULONG TokenListSize; + ULONG TokenListEntries; + ULONG ListHeaderSize; + ULONG ElementHeaderSize; +} MINIDUMP_TOKEN_INFO_LIST, *PMINIDUMP_TOKEN_INFO_LIST; + +// +// Support for arbitrary user-defined information. +// + +typedef struct _MINIDUMP_USER_RECORD { + ULONG32 Type; + MINIDUMP_LOCATION_DESCRIPTOR Memory; +} MINIDUMP_USER_RECORD, *PMINIDUMP_USER_RECORD; + + +typedef struct _MINIDUMP_USER_STREAM { + ULONG32 Type; + ULONG BufferSize; + PVOID Buffer; + +} MINIDUMP_USER_STREAM, *PMINIDUMP_USER_STREAM; + + +typedef struct _MINIDUMP_USER_STREAM_INFORMATION { + ULONG UserStreamCount; + PMINIDUMP_USER_STREAM UserStreamArray; +} MINIDUMP_USER_STREAM_INFORMATION, *PMINIDUMP_USER_STREAM_INFORMATION; + +// +// Callback support. +// + +typedef enum _MINIDUMP_CALLBACK_TYPE { + ModuleCallback, + ThreadCallback, + ThreadExCallback, + IncludeThreadCallback, + IncludeModuleCallback, + MemoryCallback, + CancelCallback, + WriteKernelMinidumpCallback, + KernelMinidumpStatusCallback, + RemoveMemoryCallback, + IncludeVmRegionCallback, + IoStartCallback, + IoWriteAllCallback, + IoFinishCallback, + ReadMemoryFailureCallback, + SecondaryFlagsCallback, +} MINIDUMP_CALLBACK_TYPE; + + +typedef struct _MINIDUMP_THREAD_CALLBACK { + ULONG ThreadId; + HANDLE ThreadHandle; + CONTEXT Context; + ULONG SizeOfContext; + ULONG64 StackBase; + ULONG64 StackEnd; +} MINIDUMP_THREAD_CALLBACK, *PMINIDUMP_THREAD_CALLBACK; + + +typedef struct _MINIDUMP_THREAD_EX_CALLBACK { + ULONG ThreadId; + HANDLE ThreadHandle; + CONTEXT Context; + ULONG SizeOfContext; + ULONG64 StackBase; + ULONG64 StackEnd; + ULONG64 BackingStoreBase; + ULONG64 BackingStoreEnd; +} MINIDUMP_THREAD_EX_CALLBACK, *PMINIDUMP_THREAD_EX_CALLBACK; + + +typedef struct _MINIDUMP_INCLUDE_THREAD_CALLBACK { + ULONG ThreadId; +} MINIDUMP_INCLUDE_THREAD_CALLBACK, *PMINIDUMP_INCLUDE_THREAD_CALLBACK; + + +typedef enum _THREAD_WRITE_FLAGS { + ThreadWriteThread = 0x0001, + ThreadWriteStack = 0x0002, + ThreadWriteContext = 0x0004, + ThreadWriteBackingStore = 0x0008, + ThreadWriteInstructionWindow = 0x0010, + ThreadWriteThreadData = 0x0020, + ThreadWriteThreadInfo = 0x0040, +} THREAD_WRITE_FLAGS; + +typedef struct _MINIDUMP_MODULE_CALLBACK { + PWCHAR FullPath; + ULONG64 BaseOfImage; + ULONG SizeOfImage; + ULONG CheckSum; + ULONG TimeDateStamp; + VS_FIXEDFILEINFO VersionInfo; + PVOID CvRecord; + ULONG SizeOfCvRecord; + PVOID MiscRecord; + ULONG SizeOfMiscRecord; +} MINIDUMP_MODULE_CALLBACK, *PMINIDUMP_MODULE_CALLBACK; + + +typedef struct _MINIDUMP_INCLUDE_MODULE_CALLBACK { + ULONG64 BaseOfImage; +} MINIDUMP_INCLUDE_MODULE_CALLBACK, *PMINIDUMP_INCLUDE_MODULE_CALLBACK; + + +typedef enum _MODULE_WRITE_FLAGS { + ModuleWriteModule = 0x0001, + ModuleWriteDataSeg = 0x0002, + ModuleWriteMiscRecord = 0x0004, + ModuleWriteCvRecord = 0x0008, + ModuleReferencedByMemory = 0x0010, + ModuleWriteTlsData = 0x0020, + ModuleWriteCodeSegs = 0x0040, +} MODULE_WRITE_FLAGS; + + +typedef struct _MINIDUMP_IO_CALLBACK { + HANDLE Handle; + ULONG64 Offset; + PVOID Buffer; + ULONG BufferBytes; +} MINIDUMP_IO_CALLBACK, *PMINIDUMP_IO_CALLBACK; + + +typedef struct _MINIDUMP_READ_MEMORY_FAILURE_CALLBACK +{ + ULONG64 Offset; + ULONG Bytes; + HRESULT FailureStatus; +} MINIDUMP_READ_MEMORY_FAILURE_CALLBACK, + *PMINIDUMP_READ_MEMORY_FAILURE_CALLBACK; + + +typedef struct _MINIDUMP_CALLBACK_INPUT { + ULONG ProcessId; + HANDLE ProcessHandle; + ULONG CallbackType; + union { + HRESULT Status; + MINIDUMP_THREAD_CALLBACK Thread; + MINIDUMP_THREAD_EX_CALLBACK ThreadEx; + MINIDUMP_MODULE_CALLBACK Module; + MINIDUMP_INCLUDE_THREAD_CALLBACK IncludeThread; + MINIDUMP_INCLUDE_MODULE_CALLBACK IncludeModule; + MINIDUMP_IO_CALLBACK Io; + MINIDUMP_READ_MEMORY_FAILURE_CALLBACK ReadMemoryFailure; + ULONG SecondaryFlags; + }; +} MINIDUMP_CALLBACK_INPUT, *PMINIDUMP_CALLBACK_INPUT; + +typedef struct _MINIDUMP_CALLBACK_OUTPUT { + union { + ULONG ModuleWriteFlags; + ULONG ThreadWriteFlags; + ULONG SecondaryFlags; + struct { + ULONG64 MemoryBase; + ULONG MemorySize; + }; + struct { + BOOL CheckCancel; + BOOL Cancel; + }; + HANDLE Handle; + struct { + MINIDUMP_MEMORY_INFO VmRegion; + BOOL Continue; + }; + HRESULT Status; + }; +} MINIDUMP_CALLBACK_OUTPUT, *PMINIDUMP_CALLBACK_OUTPUT; + + +// +// A normal minidump contains just the information +// necessary to capture stack traces for all of the +// existing threads in a process. +// +// A minidump with data segments includes all of the data +// sections from loaded modules in order to capture +// global variable contents. This can make the dump much +// larger if many modules have global data. +// +// A minidump with full memory includes all of the accessible +// memory in the process and can be very large. A minidump +// with full memory always has the raw memory data at the end +// of the dump so that the initial structures in the dump can +// be mapped directly without having to include the raw +// memory information. +// +// Stack and backing store memory can be filtered to remove +// data unnecessary for stack walking. This can improve +// compression of stacks and also deletes data that may +// be private and should not be stored in a dump. +// Memory can also be scanned to see what modules are +// referenced by stack and backing store memory to allow +// omission of other modules to reduce dump size. +// In either of these modes the ModuleReferencedByMemory flag +// is set for all modules referenced before the base +// module callbacks occur. +// +// On some operating systems a list of modules that were +// recently unloaded is kept in addition to the currently +// loaded module list. This information can be saved in +// the dump if desired. +// +// Stack and backing store memory can be scanned for referenced +// pages in order to pick up data referenced by locals or other +// stack memory. This can increase the size of a dump significantly. +// +// Module paths may contain undesired information such as user names +// or other important directory names so they can be stripped. This +// option reduces the ability to locate the proper image later +// and should only be used in certain situations. +// +// Complete operating system per-process and per-thread information can +// be gathered and stored in the dump. +// +// The virtual address space can be scanned for various types +// of memory to be included in the dump. +// +// Code which is concerned with potentially private information +// getting into the minidump can set a flag that automatically +// modifies all existing and future flags to avoid placing +// unnecessary data in the dump. Basic data, such as stack +// information, will still be included but optional data, such +// as indirect memory, will not. +// +// When doing a full memory dump it's possible to store all +// of the enumerated memory region descriptive information +// in a memory information stream. +// +// Additional thread information beyond the basic thread +// structure can be collected if desired. +// +// A minidump with code segments includes all of the code +// and code-related sections from loaded modules in order +// to capture executable content. +// +// MiniDumpWithoutAuxiliaryState turns off any secondary, +// auxiliary-supported memory gathering. +// +// MiniDumpWithFullAuxiliaryState asks any present auxiliary +// data providers to include all of their state in the dump. +// The exact set of what is provided depends on the auxiliary. +// This can be quite large. +// + +typedef enum _MINIDUMP_TYPE { + MiniDumpNormal = 0x00000000, + MiniDumpWithDataSegs = 0x00000001, + MiniDumpWithFullMemory = 0x00000002, + MiniDumpWithHandleData = 0x00000004, + MiniDumpFilterMemory = 0x00000008, + MiniDumpScanMemory = 0x00000010, + MiniDumpWithUnloadedModules = 0x00000020, + MiniDumpWithIndirectlyReferencedMemory = 0x00000040, + MiniDumpFilterModulePaths = 0x00000080, + MiniDumpWithProcessThreadData = 0x00000100, + MiniDumpWithPrivateReadWriteMemory = 0x00000200, + MiniDumpWithoutOptionalData = 0x00000400, + MiniDumpWithFullMemoryInfo = 0x00000800, + MiniDumpWithThreadInfo = 0x00001000, + MiniDumpWithCodeSegs = 0x00002000, + MiniDumpWithoutAuxiliaryState = 0x00004000, + MiniDumpWithFullAuxiliaryState = 0x00008000, + MiniDumpWithPrivateWriteCopyMemory = 0x00010000, + MiniDumpIgnoreInaccessibleMemory = 0x00020000, + MiniDumpWithTokenInformation = 0x00040000, + MiniDumpValidTypeFlags = 0x0007ffff, +} MINIDUMP_TYPE; + +// +// In addition to the primary flags provided to +// MiniDumpWriteDump there are additional, less +// frequently used options queried via the secondary +// flags callback. +// +// MiniSecondaryWithoutPowerInfo suppresses the minidump +// query that retrieves processor power information for +// MINIDUMP_MISC_INFO. +// + +typedef enum _MINIDUMP_SECONDARY_FLAGS { + MiniSecondaryWithoutPowerInfo = 0x00000001, + + MiniSecondaryValidFlags = 0x00000001, +} MINIDUMP_SECONDARY_FLAGS; + + +// +// The minidump callback should modify the FieldsToWrite parameter to reflect +// what portions of the specified thread or module should be written to the +// file. +// + +typedef +BOOL +(WINAPI * MINIDUMP_CALLBACK_ROUTINE) ( + __inout PVOID CallbackParam, + __in PMINIDUMP_CALLBACK_INPUT CallbackInput, + __inout PMINIDUMP_CALLBACK_OUTPUT CallbackOutput + ); + +typedef struct _MINIDUMP_CALLBACK_INFORMATION { + MINIDUMP_CALLBACK_ROUTINE CallbackRoutine; + PVOID CallbackParam; +} MINIDUMP_CALLBACK_INFORMATION, *PMINIDUMP_CALLBACK_INFORMATION; + + + +//++ +// +// PVOID +// RVA_TO_ADDR( +// PVOID Mapping, +// ULONG Rva +// ) +// +// Routine Description: +// +// Map an RVA that is contained within a mapped file to it's associated +// flat address. +// +// Arguments: +// +// Mapping - Base address of mapped file containing the RVA. +// +// Rva - An Rva to fixup. +// +// Return Values: +// +// A pointer to the desired data. +// +//-- + +#define RVA_TO_ADDR(Mapping,Rva) ((PVOID)(((ULONG_PTR) (Mapping)) + (Rva))) + +BOOL +WINAPI +MiniDumpWriteDump( + __in HANDLE hProcess, + __in DWORD ProcessId, + __in HANDLE hFile, + __in MINIDUMP_TYPE DumpType, + __in_opt PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, + __in_opt PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, + __in_opt PMINIDUMP_CALLBACK_INFORMATION CallbackParam + ); + +BOOL +WINAPI +MiniDumpReadDumpStream( + __in PVOID BaseOfDump, + __in ULONG StreamNumber, + __deref_out_opt PMINIDUMP_DIRECTORY * Dir, + __deref_out_opt PVOID * StreamPointer, + __out_opt ULONG * StreamSize + ); + +#if defined(_MSC_VER) +#if _MSC_VER >= 800 +#if _MSC_VER >= 1200 +#pragma warning(pop) +#else +#pragma warning(default:4200) /* Zero length array */ +#pragma warning(default:4201) /* Nameless struct/union */ +#endif +#endif +#endif + +#include + +#ifdef __cplusplus +} +#endif + + +#endif // _DBGHELP_ + diff --git a/utils/EBK.h b/utils/EBK.h new file mode 100644 index 0000000..e52c79b --- /dev/null +++ b/utils/EBK.h @@ -0,0 +1,2133 @@ +/*++ BUILD Version: 0000 Increment this if a change has global effects + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + ntsecpkg.h + +Abstract: + + This module defines the structures and APIs for use by a + authentication or security package. + +Revision History: + +--*/ + +#ifndef _NTSECPKG_ +#define _NTSECPKG_ + +#ifdef __cplusplus +extern "C" { +#endif + + +///////////////////////////////////////////////////////////////////////// +// // +// Data types used by authentication packages // +// // +///////////////////////////////////////////////////////////////////////// + +// +// opaque data type which represents a client request +// + +typedef PVOID *PLSA_CLIENT_REQUEST; + + +// +// When a logon of a user is requested, the authentication package +// is expected to return one of the following structures indicating +// the contents of a user's token. +// + +typedef enum _LSA_TOKEN_INFORMATION_TYPE { + LsaTokenInformationNull, // Implies LSA_TOKEN_INFORMATION_NULL data type + LsaTokenInformationV1, // Implies LSA_TOKEN_INFORMATION_V1 data type + LsaTokenInformationV2 // Implies LSA_TOKEN_INFORMATION_V2 data type +} LSA_TOKEN_INFORMATION_TYPE, *PLSA_TOKEN_INFORMATION_TYPE; + + +// +// The NULL information is used in cases where a non-authenticated +// system access is needed. For example, a non-authentication network +// circuit (such as LAN Manager's null session) can be given NULL +// information. This will result in an anonymous token being generated +// for the logon that gives the user no ability to access protected system +// resources, but does allow access to non-protected system resources. +// + +typedef struct _LSA_TOKEN_INFORMATION_NULL { + + // + // Time at which the security context becomes invalid. + // Use a value in the distant future if the context + // never expires. + // + + LARGE_INTEGER ExpirationTime; + + // + // The SID(s) of groups the user is to be made a member of. This should + // not include WORLD or other system defined and assigned + // SIDs. These will be added automatically by LSA. + // + // Each SID is expected to be in a separately allocated block + // of memory. The TOKEN_GROUPS structure is also expected to + // be in a separately allocated block of memory. + // + + PTOKEN_GROUPS Groups; + +} LSA_TOKEN_INFORMATION_NULL, *PLSA_TOKEN_INFORMATION_NULL; + + +// +// The V1 token information structure is superceeded by the V2 token +// information structure. The V1 strucure should only be used for +// backwards compatability. +// This structure contains information that an authentication package +// can place in a Version 1 NT token object. +// + +typedef struct _LSA_TOKEN_INFORMATION_V1 { + + // + // Time at which the security context becomes invalid. + // Use a value in the distant future if the context + // never expires. + // + + LARGE_INTEGER ExpirationTime; + + // + // The SID of the user logging on. The SID value is in a + // separately allocated block of memory. + // + + TOKEN_USER User; + + // + // The SID(s) of groups the user is a member of. This should + // not include WORLD or other system defined and assigned + // SIDs. These will be added automatically by LSA. + // + // Each SID is expected to be in a separately allocated block + // of memory. The TOKEN_GROUPS structure is also expected to + // be in a separately allocated block of memory. + // + + PTOKEN_GROUPS Groups; + + // + // This field is used to establish the primary group of the user. + // This value does not have to correspond to one of the SIDs + // assigned to the user. + // + // The SID pointed to by this structure is expected to be in + // a separately allocated block of memory. + // + // This field is mandatory and must be filled in. + // + + TOKEN_PRIMARY_GROUP PrimaryGroup; + + + + // + // The privileges the user is assigned. This list of privileges + // will be augmented or over-ridden by any local security policy + // assigned privileges. + // + // Each privilege is expected to be in a separately allocated + // block of memory. The TOKEN_PRIVILEGES structure is also + // expected to be in a separately allocated block of memory. + // + // If there are no privileges to assign to the user, this field + // may be set to NULL. + // + + PTOKEN_PRIVILEGES Privileges; + + + + // + // This field may be used to establish an explicit default + // owner. Normally, the user ID is used as the default owner. + // If another value is desired, it must be specified here. + // + // The Owner.Sid field may be set to NULL to indicate there is no + // alternate default owner value. + // + + TOKEN_OWNER Owner; + + // + // This field may be used to establish a default + // protection for the user. If no value is provided, then + // a default protection that grants everyone all access will + // be established. + // + // The DefaultDacl.DefaultDacl field may be set to NULL to indicate + // there is no default protection. + // + + TOKEN_DEFAULT_DACL DefaultDacl; + +} LSA_TOKEN_INFORMATION_V1, *PLSA_TOKEN_INFORMATION_V1; + +// +// The V2 information is used in most cases of logon. The structure is identical +// to the V1 token information structure, with the exception that the memory allocation +// is handled differently. The LSA_TOKEN_INFORMATION_V2 structure is intended to be +// allocated monolithiclly, with the privileges, DACL, sids, and group array either part of +// same allocation, or allocated and freed externally. +// + +typedef LSA_TOKEN_INFORMATION_V1 LSA_TOKEN_INFORMATION_V2, *PLSA_TOKEN_INFORMATION_V2; + + +///////////////////////////////////////////////////////////////////////// +// // +// Interface definitions available for use by authentication packages // +// // +///////////////////////////////////////////////////////////////////////// + + + +typedef NTSTATUS +(NTAPI LSA_CREATE_LOGON_SESSION) ( + IN PLUID LogonId + ); + +typedef NTSTATUS +(NTAPI LSA_DELETE_LOGON_SESSION) ( + IN PLUID LogonId + ); + +typedef NTSTATUS +(NTAPI LSA_ADD_CREDENTIAL) ( + IN PLUID LogonId, + IN ULONG AuthenticationPackage, + IN PLSA_STRING PrimaryKeyValue, + IN PLSA_STRING Credentials + ); + +typedef NTSTATUS +(NTAPI LSA_GET_CREDENTIALS) ( + IN PLUID LogonId, + IN ULONG AuthenticationPackage, + IN OUT PULONG QueryContext, + IN BOOLEAN RetrieveAllCredentials, + IN PLSA_STRING PrimaryKeyValue, + OUT PULONG PrimaryKeyLength, + IN PLSA_STRING Credentials + ); + +typedef NTSTATUS +(NTAPI LSA_DELETE_CREDENTIAL) ( + IN PLUID LogonId, + IN ULONG AuthenticationPackage, + IN PLSA_STRING PrimaryKeyValue + ); + +typedef PVOID +(NTAPI LSA_ALLOCATE_LSA_HEAP) ( + IN ULONG Length + ); + +typedef VOID +(NTAPI LSA_FREE_LSA_HEAP) ( + IN PVOID Base + ); + +typedef PVOID +(NTAPI LSA_ALLOCATE_PRIVATE_HEAP) ( + IN SIZE_T Length + ); + +typedef VOID +(NTAPI LSA_FREE_PRIVATE_HEAP) ( + IN PVOID Base + ); + +typedef NTSTATUS +(NTAPI LSA_ALLOCATE_CLIENT_BUFFER) ( + IN PLSA_CLIENT_REQUEST ClientRequest, + IN ULONG LengthRequired, + OUT PVOID *ClientBaseAddress + ); + +typedef NTSTATUS +(NTAPI LSA_FREE_CLIENT_BUFFER) ( + IN PLSA_CLIENT_REQUEST ClientRequest, + IN PVOID ClientBaseAddress + ); + +typedef NTSTATUS +(NTAPI LSA_COPY_TO_CLIENT_BUFFER) ( + IN PLSA_CLIENT_REQUEST ClientRequest, + IN ULONG Length, + IN PVOID ClientBaseAddress, + IN PVOID BufferToCopy + ); + +typedef NTSTATUS +(NTAPI LSA_COPY_FROM_CLIENT_BUFFER) ( + IN PLSA_CLIENT_REQUEST ClientRequest, + IN ULONG Length, + IN PVOID BufferToCopy, + IN PVOID ClientBaseAddress + ); + +typedef LSA_CREATE_LOGON_SESSION * PLSA_CREATE_LOGON_SESSION; +typedef LSA_DELETE_LOGON_SESSION * PLSA_DELETE_LOGON_SESSION; +typedef LSA_ADD_CREDENTIAL * PLSA_ADD_CREDENTIAL; +typedef LSA_GET_CREDENTIALS * PLSA_GET_CREDENTIALS; +typedef LSA_DELETE_CREDENTIAL * PLSA_DELETE_CREDENTIAL; +typedef LSA_ALLOCATE_LSA_HEAP * PLSA_ALLOCATE_LSA_HEAP; +typedef LSA_FREE_LSA_HEAP * PLSA_FREE_LSA_HEAP; +typedef LSA_ALLOCATE_PRIVATE_HEAP * PLSA_ALLOCATE_PRIVATE_HEAP; +typedef LSA_FREE_PRIVATE_HEAP * PLSA_FREE_PRIVATE_HEAP; +typedef LSA_ALLOCATE_CLIENT_BUFFER * PLSA_ALLOCATE_CLIENT_BUFFER; +typedef LSA_FREE_CLIENT_BUFFER * PLSA_FREE_CLIENT_BUFFER; +typedef LSA_COPY_TO_CLIENT_BUFFER * PLSA_COPY_TO_CLIENT_BUFFER; +typedef LSA_COPY_FROM_CLIENT_BUFFER * PLSA_COPY_FROM_CLIENT_BUFFER; + +// +// The dispatch table of LSA services which are available to +// authentication packages. +// +typedef struct _LSA_DISPATCH_TABLE { + PLSA_CREATE_LOGON_SESSION CreateLogonSession; + PLSA_DELETE_LOGON_SESSION DeleteLogonSession; + PLSA_ADD_CREDENTIAL AddCredential; + PLSA_GET_CREDENTIALS GetCredentials; + PLSA_DELETE_CREDENTIAL DeleteCredential; + PLSA_ALLOCATE_LSA_HEAP AllocateLsaHeap; + PLSA_FREE_LSA_HEAP FreeLsaHeap; + PLSA_ALLOCATE_CLIENT_BUFFER AllocateClientBuffer; + PLSA_FREE_CLIENT_BUFFER FreeClientBuffer; + PLSA_COPY_TO_CLIENT_BUFFER CopyToClientBuffer; + PLSA_COPY_FROM_CLIENT_BUFFER CopyFromClientBuffer; +} LSA_DISPATCH_TABLE, *PLSA_DISPATCH_TABLE; + + + +//////////////////////////////////////////////////////////////////////////// +// // +// Interface definitions of services provided by authentication packages // +// // +//////////////////////////////////////////////////////////////////////////// + + + +// +// Routine names +// +// The routines provided by the DLL must be assigned the following names +// so that their addresses can be retrieved when the DLL is loaded. +// + +#define LSA_AP_NAME_INITIALIZE_PACKAGE "LsaApInitializePackage\0" +#define LSA_AP_NAME_LOGON_USER "LsaApLogonUser\0" +#define LSA_AP_NAME_LOGON_USER_EX "LsaApLogonUserEx\0" +#define LSA_AP_NAME_CALL_PACKAGE "LsaApCallPackage\0" +#define LSA_AP_NAME_LOGON_TERMINATED "LsaApLogonTerminated\0" +#define LSA_AP_NAME_CALL_PACKAGE_UNTRUSTED "LsaApCallPackageUntrusted\0" +#define LSA_AP_NAME_CALL_PACKAGE_PASSTHROUGH "LsaApCallPackagePassthrough\0" + + +// +// Routine templates +// + + +typedef NTSTATUS +(NTAPI LSA_AP_INITIALIZE_PACKAGE) ( + IN ULONG AuthenticationPackageId, + IN PLSA_DISPATCH_TABLE LsaDispatchTable, + IN PLSA_STRING Database OPTIONAL, + IN PLSA_STRING Confidentiality OPTIONAL, + OUT PLSA_STRING *AuthenticationPackageName + ); + +typedef NTSTATUS +(NTAPI LSA_AP_LOGON_USER) ( + IN PLSA_CLIENT_REQUEST ClientRequest, + IN SECURITY_LOGON_TYPE LogonType, + IN PVOID AuthenticationInformation, + IN PVOID ClientAuthenticationBase, + IN ULONG AuthenticationInformationLength, + OUT PVOID *ProfileBuffer, + OUT PULONG ProfileBufferLength, + OUT PLUID LogonId, + OUT PNTSTATUS SubStatus, + OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType, + OUT PVOID *TokenInformation, + OUT PLSA_UNICODE_STRING *AccountName, + OUT PLSA_UNICODE_STRING *AuthenticatingAuthority + ); + +typedef NTSTATUS +(NTAPI LSA_AP_LOGON_USER_EX) ( + IN PLSA_CLIENT_REQUEST ClientRequest, + IN SECURITY_LOGON_TYPE LogonType, + IN PVOID AuthenticationInformation, + IN PVOID ClientAuthenticationBase, + IN ULONG AuthenticationInformationLength, + OUT PVOID *ProfileBuffer, + OUT PULONG ProfileBufferLength, + OUT PLUID LogonId, + OUT PNTSTATUS SubStatus, + OUT PLSA_TOKEN_INFORMATION_TYPE TokenInformationType, + OUT PVOID *TokenInformation, + OUT PUNICODE_STRING *AccountName, + OUT PUNICODE_STRING *AuthenticatingAuthority, + OUT PUNICODE_STRING *MachineName + ); + +typedef NTSTATUS +(NTAPI LSA_AP_CALL_PACKAGE) ( + IN PLSA_CLIENT_REQUEST ClientRequest, + IN PVOID ProtocolSubmitBuffer, + IN PVOID ClientBufferBase, + IN ULONG SubmitBufferLength, + OUT PVOID *ProtocolReturnBuffer, + OUT PULONG ReturnBufferLength, + OUT PNTSTATUS ProtocolStatus + ); + +typedef NTSTATUS +(NTAPI LSA_AP_CALL_PACKAGE_PASSTHROUGH) ( + IN PLSA_CLIENT_REQUEST ClientRequest, + IN PVOID ProtocolSubmitBuffer, + IN PVOID ClientBufferBase, + IN ULONG SubmitBufferLength, + OUT PVOID *ProtocolReturnBuffer, + OUT PULONG ReturnBufferLength, + OUT PNTSTATUS ProtocolStatus + ); + +typedef VOID +(NTAPI LSA_AP_LOGON_TERMINATED) ( + IN PLUID LogonId + ); + +typedef LSA_AP_CALL_PACKAGE LSA_AP_CALL_PACKAGE_UNTRUSTED; + +typedef LSA_AP_INITIALIZE_PACKAGE * PLSA_AP_INITIALIZE_PACKAGE; +typedef LSA_AP_LOGON_USER * PLSA_AP_LOGON_USER; +typedef LSA_AP_LOGON_USER_EX * PLSA_AP_LOGON_USER_EX; +typedef LSA_AP_CALL_PACKAGE * PLSA_AP_CALL_PACKAGE; +typedef LSA_AP_CALL_PACKAGE_PASSTHROUGH * PLSA_AP_CALL_PACKAGE_PASSTHROUGH; +typedef LSA_AP_LOGON_TERMINATED * PLSA_AP_LOGON_TERMINATED; +typedef LSA_AP_CALL_PACKAGE_UNTRUSTED * PLSA_AP_CALL_PACKAGE_UNTRUSTED; + + +#ifndef _SAM_CREDENTIAL_UPDATE_DEFINED +#define _SAM_CREDENTIAL_UPDATE_DEFINED + +typedef NTSTATUS (*PSAM_CREDENTIAL_UPDATE_NOTIFY_ROUTINE) ( + __in PUNICODE_STRING ClearPassword, + __in_bcount(OldCredentialSize) PVOID OldCredentials, + __in ULONG OldCredentialSize, + __in ULONG UserAccountControl, + __in_opt PUNICODE_STRING UPN, + __in PUNICODE_STRING UserName, + __in PUNICODE_STRING NetbiosDomainName, + __in PUNICODE_STRING DnsDomainName, + __deref_out_bcount(*NewCredentialSize) PVOID * NewCredentials, + __out ULONG * NewCredentialSize + ); + +#define SAM_CREDENTIAL_UPDATE_NOTIFY_ROUTINE "CredentialUpdateNotify" + +typedef BOOLEAN (*PSAM_CREDENTIAL_UPDATE_REGISTER_ROUTINE) ( + __out PUNICODE_STRING CredentialName + ); + +#define SAM_CREDENTIAL_UPDATE_REGISTER_ROUTINE "CredentialUpdateRegister" + +typedef VOID (*PSAM_CREDENTIAL_UPDATE_FREE_ROUTINE) ( + __in PVOID p + ); + +#define SAM_CREDENTIAL_UPDATE_FREE_ROUTINE "CredentialUpdateFree" + +typedef struct { + PSTR Original; + PSTR Mapped; + BOOLEAN Continuable; // only honored for some operations +} SAM_REGISTER_MAPPING_ELEMENT, *PSAM_REGISTER_MAPPING_ELEMENT; + +typedef struct { + ULONG Count; + __ecount(Count) PSAM_REGISTER_MAPPING_ELEMENT Elements; +} SAM_REGISTER_MAPPING_LIST, *PSAM_REGISTER_MAPPING_LIST; + +typedef struct { + ULONG Count; + __ecount(Count) PSAM_REGISTER_MAPPING_LIST Lists; +} SAM_REGISTER_MAPPING_TABLE, *PSAM_REGISTER_MAPPING_TABLE; + +typedef NTSTATUS (*PSAM_CREDENTIAL_UPDATE_REGISTER_MAPPED_ENTRYPOINTS_ROUTINE) ( + __out SAM_REGISTER_MAPPING_TABLE *Table + ); + +#define SAM_CREDENTIAL_UPDATE_REGISTER_MAPPED_ENTRYPOINTS_ROUTINE "RegisterMappedEntrypoints" + +#endif // _SAM_CREDENTIAL_UPDATE_DEFINED + + +#ifdef SECURITY_KERNEL +// +// Can't use the windows.h def'ns in kernel mode. +// +typedef PVOID SEC_THREAD_START; +typedef PVOID SEC_ATTRS; +#else +typedef LPTHREAD_START_ROUTINE SEC_THREAD_START; +typedef LPSECURITY_ATTRIBUTES SEC_ATTRS; +#endif + + +#define SecEqualLuid(L1, L2) \ + ( ( ((PLUID)L1)->LowPart == ((PLUID)L2)->LowPart ) && \ + ( ((PLUID)L1)->HighPart == ((PLUID)L2)->HighPart ) ) \ + +#define SecIsZeroLuid( L1 ) \ + ( ( L1->LowPart | L1->HighPart ) == 0 ) + +// +// The following structures are used by the helper functions +// + +typedef struct _SECPKG_CLIENT_INFO { + LUID LogonId; // Effective Logon Id + ULONG ProcessID; // Process Id of caller + ULONG ThreadID; // Thread Id of caller + BOOLEAN HasTcbPrivilege; // Client has TCB + BOOLEAN Impersonating; // Client is impersonating + BOOLEAN Restricted; // Client is restricted + + // + // NT 5.1 + // + + UCHAR ClientFlags; // Extra flags about the client + SECURITY_IMPERSONATION_LEVEL ImpersonationLevel; // Impersonation level of client + + // + // NT 6 + // + + HANDLE ClientToken; + +} SECPKG_CLIENT_INFO, * PSECPKG_CLIENT_INFO; + +#define SECPKG_CLIENT_PROCESS_TERMINATED 0x01 // The client process has terminated +#define SECPKG_CLIENT_THREAD_TERMINATED 0x02 // The client thread has terminated + +typedef struct _SECPKG_CALL_INFO { + ULONG ProcessId; + ULONG ThreadId; + ULONG Attributes; + ULONG CallCount; + PVOID MechOid; // mechanism objection identifer +} SECPKG_CALL_INFO, * PSECPKG_CALL_INFO; + +#define SECPKG_CALL_KERNEL_MODE 0x00000001 // Call originated in kernel mode +#define SECPKG_CALL_ANSI 0x00000002 // Call came from ANSI stub +#define SECPKG_CALL_URGENT 0x00000004 // Call designated urgent +#define SECPKG_CALL_RECURSIVE 0x00000008 // Call is recursing +#define SECPKG_CALL_IN_PROC 0x00000010 // Call originated in process +#define SECPKG_CALL_CLEANUP 0x00000020 // Call is cleanup from a client +#define SECPKG_CALL_WOWCLIENT 0x00000040 // Call is from a WOW client process +#define SECPKG_CALL_THREAD_TERM 0x00000080 // Call is from a thread that has term'd +#define SECPKG_CALL_PROCESS_TERM 0x00000100 // Call is from a process that has term'd +#define SECPKG_CALL_IS_TCB 0x00000200 // Call is from TCB +#define SECPKG_CALL_NETWORK_ONLY 0x00000400 // Call asks for network logon only, no cached logons +#define SECPKG_CALL_WINLOGON 0x00000800 // the caller of LsaLogonuser() is Winlogon +#define SECPKG_CALL_ASYNC_UPDATE 0x00001000 // asynchronous update for unlock +#define SECPKG_CALL_SYSTEM_PROC 0x00002000 // Call originated from the System process +#define SECPKG_CALL_NEGO 0x00004000 // Called by SPNEGO +#define SECPKG_CALL_NEGO_EXTENDER 0x00008000 // Called by NEGO extender +#define SECPKG_CALL_BUFFER_MARSHAL 0x00010000 // Buffer passed is marshaled (by RPC) + +typedef struct _SECPKG_SUPPLEMENTAL_CRED { + UNICODE_STRING PackageName; + ULONG CredentialSize; +#ifdef MIDL_PASS + [size_is(CredentialSize)] +#endif // MIDL_PASS + PUCHAR Credentials; +} SECPKG_SUPPLEMENTAL_CRED, *PSECPKG_SUPPLEMENTAL_CRED; + +typedef struct _SECPKG_BYTE_VECTOR +{ + ULONG ByteArrayOffset; // each element is a byte + USHORT ByteArrayLength; +} SECPKG_BYTE_VECTOR, *PSECPKG_BYTE_VECTOR; + +typedef struct _SECPKG_SHORT_VECTOR +{ + ULONG ShortArrayOffset; // each element is a short + USHORT ShortArrayCount; // number of characters +} SECPKG_SHORT_VECTOR, *PSECPKG_SHORT_VECTOR; + +// +// the supplied credential structure +// + +typedef struct _SECPKG_SUPPLIED_CREDENTIAL { + USHORT cbHeaderLength; // the length of the header + USHORT cbStructureLength; // pay load length including the header + SECPKG_SHORT_VECTOR UserName; // unicode only + SECPKG_SHORT_VECTOR DomainName; // unicode only + SECPKG_BYTE_VECTOR PackedCredentials; // SEC_WINNT_AUTH_PACKED_CREDENTIALS + ULONG CredFlags; // authidentity flags +} SECPKG_SUPPLIED_CREDENTIAL, *PSECPKG_SUPPLIED_CREDENTIAL; + +// +// the credential structure used by Nego2-SPMI +// + +#define SECPKG_CREDENTIAL_VERSION 201 + +// +// credentials flags +// + +#define SECPKG_CREDENTIAL_FLAGS_CALLER_HAS_TCB 0x1 + +typedef struct _SECPKG_CREDENTIAL { + ULONG64 Version; // contains SECPKG_CREDENTIAL_VERSION + USHORT cbHeaderLength; // the length of the header + ULONG cbStructureLength; // pay load length including the header, + // all the content of this structure is within a contiguous buffer + ULONG ClientProcess; // the caller's identity + ULONG ClientThread; // the caller's identity + LUID LogonId; // the caller's identity + HANDLE ClientToken; // the caller's identity + ULONG SessionId; // the caller's identity + LUID ModifiedId; // the caller's identity + ULONG fCredentials; // inbound or outbound? + ULONG Flags; // contains SECPKG_CREDENTIAL_FLAGS + SECPKG_BYTE_VECTOR PrincipalName; // not used + SECPKG_BYTE_VECTOR PackageList; // list of packages, relevant only to SPNEGO + SECPKG_BYTE_VECTOR MarshaledSuppliedCreds; // contains a SECPKG_SUPPLIED_CREDENTIAL structure +} SECPKG_CREDENTIAL, *PSECPKG_CREDENTIAL; + +typedef ULONG_PTR LSA_SEC_HANDLE; +typedef LSA_SEC_HANDLE * PLSA_SEC_HANDLE; +typedef struct _SECPKG_SUPPLEMENTAL_CRED_ARRAY { + ULONG CredentialCount; +#ifdef MIDL_PASS + [size_is(CredentialCount)] SECPKG_SUPPLEMENTAL_CRED Credentials[*]; +#else // MIDL_PASS + SECPKG_SUPPLEMENTAL_CRED Credentials[1]; +#endif // MIDL_PASS +} SECPKG_SUPPLEMENTAL_CRED_ARRAY, *PSECPKG_SUPPLEMENTAL_CRED_ARRAY; + +// +// This flag is used for to indicate which buffers in the LSA are located +// in the client's address space +// + +#define SECBUFFER_UNMAPPED 0x40000000 + +// +// This flag is used to indicate that the buffer was mapped into the LSA +// from kernel mode. +// + +#define SECBUFFER_KERNEL_MAP 0x20000000 + +typedef NTSTATUS +(NTAPI LSA_CALLBACK_FUNCTION)( + ULONG_PTR Argument1, + ULONG_PTR Argument2, + PSecBuffer InputBuffer, + PSecBuffer OutputBuffer + ); + +typedef LSA_CALLBACK_FUNCTION * PLSA_CALLBACK_FUNCTION; + + + +#define PRIMARY_CRED_CLEAR_PASSWORD 0x1 +#define PRIMARY_CRED_OWF_PASSWORD 0x2 +#define PRIMARY_CRED_UPDATE 0x4 // this is a change of existing creds +#define PRIMARY_CRED_CACHED_LOGON 0x8 +#define PRIMARY_CRED_LOGON_NO_TCB 0x10 +#define PRIMARY_CRED_LOGON_LUA 0x20 +#define PRIMARY_CRED_INTERACTIVE_SMARTCARD_LOGON 0x40 +#define PRIMARY_CRED_REFRESH_NEEDED 0x80 // unlock refresh needed + + +#define PRIMARY_CRED_LOGON_PACKAGE_SHIFT 24 +#define PRIMARY_CRED_PACKAGE_MASK 0xff000000 + +// +// For cached logons, the RPC id of the package doing the logon is identified +// by shifting the flags to the right by the PRIMARY_CRED_LOGON_PACKAGE_SHIFT. +// + +typedef struct _SECPKG_PRIMARY_CRED { + LUID LogonId; + UNICODE_STRING DownlevelName; // Sam Account Name + UNICODE_STRING DomainName; // Netbios domain name where account is located + UNICODE_STRING Password; + UNICODE_STRING OldPassword; + PSID UserSid; + ULONG Flags; + UNICODE_STRING DnsDomainName; // DNS domain name where account is located (if known) + UNICODE_STRING Upn; // UPN of account (if known) + + UNICODE_STRING LogonServer; + UNICODE_STRING Spare1; + UNICODE_STRING Spare2; + UNICODE_STRING Spare3; + UNICODE_STRING Spare4; +} SECPKG_PRIMARY_CRED, *PSECPKG_PRIMARY_CRED; + +// +// Maximum size of stored credentials. +// + +#define MAX_CRED_SIZE 1024 + +// Values for MachineState + +#define SECPKG_STATE_ENCRYPTION_PERMITTED 0x01 +#define SECPKG_STATE_STRONG_ENCRYPTION_PERMITTED 0x02 +#define SECPKG_STATE_DOMAIN_CONTROLLER 0x04 +#define SECPKG_STATE_WORKSTATION 0x08 +#define SECPKG_STATE_STANDALONE 0x10 + +typedef struct _SECPKG_PARAMETERS { + ULONG Version; + ULONG MachineState; + ULONG SetupMode; + PSID DomainSid; + UNICODE_STRING DomainName; + UNICODE_STRING DnsDomainName; + GUID DomainGuid; +} SECPKG_PARAMETERS, *PSECPKG_PARAMETERS; + + +// +// Extended Package information structures +// + +typedef enum _SECPKG_EXTENDED_INFORMATION_CLASS { + SecpkgGssInfo = 1, + SecpkgContextThunks, + SecpkgMutualAuthLevel, + SecpkgWowClientDll, + SecpkgExtraOids, + SecpkgMaxInfo, + SecpkgNego2Info, +} SECPKG_EXTENDED_INFORMATION_CLASS; + +typedef struct _SECPKG_GSS_INFO { + ULONG EncodedIdLength; + UCHAR EncodedId[4]; +} SECPKG_GSS_INFO, * PSECPKG_GSS_INFO; + +typedef struct _SECPKG_CONTEXT_THUNKS { + ULONG InfoLevelCount; + ULONG Levels[1]; +} SECPKG_CONTEXT_THUNKS, *PSECPKG_CONTEXT_THUNKS; + +typedef struct _SECPKG_MUTUAL_AUTH_LEVEL { + ULONG MutualAuthLevel; +} SECPKG_MUTUAL_AUTH_LEVEL, * PSECPKG_MUTUAL_AUTH_LEVEL; + +typedef struct _SECPKG_WOW_CLIENT_DLL { + SECURITY_STRING WowClientDllPath; +} SECPKG_WOW_CLIENT_DLL, * PSECPKG_WOW_CLIENT_DLL; + +#define SECPKG_MAX_OID_LENGTH 32 + +typedef struct _SECPKG_SERIALIZED_OID { + ULONG OidLength; + ULONG OidAttributes; + UCHAR OidValue[ SECPKG_MAX_OID_LENGTH ]; +} SECPKG_SERIALIZED_OID, * PSECPKG_SERIALIZED_OID; + +typedef struct _SECPKG_EXTRA_OIDS { + ULONG OidCount; + SECPKG_SERIALIZED_OID Oids[ 1 ]; +} SECPKG_EXTRA_OIDS, * PSECPKG_EXTRA_OIDS; + +// used by Nego2 +typedef struct _SECPKG_NEGO2_INFO { + UCHAR AuthScheme[16]; // auth id + ULONG PackageFlags; +} SECPKG_NEGO2_INFO, * PSECPKG_NEGO2_INFO; + +typedef struct _SECPKG_EXTENDED_INFORMATION { + SECPKG_EXTENDED_INFORMATION_CLASS Class; + union { + SECPKG_GSS_INFO GssInfo; + SECPKG_CONTEXT_THUNKS ContextThunks; + SECPKG_MUTUAL_AUTH_LEVEL MutualAuthLevel; + SECPKG_WOW_CLIENT_DLL WowClientDll; + SECPKG_EXTRA_OIDS ExtraOids; + SECPKG_NEGO2_INFO Nego2Info; + } Info; +} SECPKG_EXTENDED_INFORMATION, * PSECPKG_EXTENDED_INFORMATION; + +typedef struct _SECPKG_TARGETINFO +{ + PSID DomainSid; + PCWSTR ComputerName; +} SECPKG_TARGETINFO, *PSECPKG_TARGETINFO; + +#define SECPKG_ATTR_SASL_CONTEXT 0x00010000 + +typedef struct _SecPkgContext_SaslContext { + PVOID SaslContext; +} SecPkgContext_SaslContext, * PSecPkgContext_SaslContext; + +// +// Setting this value as the first context thunk value will cause all +// calls to go to the LSA: +// + +#define SECPKG_ATTR_THUNK_ALL 0x00010000 + + +#ifndef SECURITY_USER_DATA_DEFINED +#define SECURITY_USER_DATA_DEFINED + +typedef struct _SECURITY_USER_DATA { + SECURITY_STRING UserName; // User name + SECURITY_STRING LogonDomainName; // Domain the user logged on to + SECURITY_STRING LogonServer; // Server that logged the user on + PSID pSid; // SID of user +} SECURITY_USER_DATA, *PSECURITY_USER_DATA; + +typedef SECURITY_USER_DATA SecurityUserData, * PSecurityUserData; + + +#define UNDERSTANDS_LONG_NAMES 1 +#define NO_LONG_NAMES 2 + +#endif // SECURITY_USER_DATA_DEFINED + +////////////////////////////////////////////////////////////////////////// +// +// The following prototypes are to functions that are provided by the SPMgr +// to security packages. +// +////////////////////////////////////////////////////////////////////////// + +typedef NTSTATUS +(NTAPI LSA_IMPERSONATE_CLIENT) ( + VOID + ); + + +typedef NTSTATUS +(NTAPI LSA_UNLOAD_PACKAGE)( + VOID + ); + +typedef NTSTATUS +(NTAPI LSA_DUPLICATE_HANDLE)( + IN HANDLE SourceHandle, + OUT PHANDLE DestionationHandle); + + +typedef NTSTATUS +(NTAPI LSA_SAVE_SUPPLEMENTAL_CREDENTIALS)( + IN PLUID LogonId, + IN ULONG SupplementalCredSize, + IN PVOID SupplementalCreds, + IN BOOLEAN Synchronous + ); + + +typedef HANDLE +(NTAPI LSA_CREATE_THREAD)( + IN SEC_ATTRS SecurityAttributes, + IN ULONG StackSize, + IN SEC_THREAD_START StartFunction, + IN PVOID ThreadParameter, + IN ULONG CreationFlags, + OUT PULONG ThreadId + ); + + +typedef NTSTATUS +(NTAPI LSA_GET_CLIENT_INFO)( + OUT PSECPKG_CLIENT_INFO ClientInfo + ); + + +typedef HANDLE +(NTAPI LSA_REGISTER_NOTIFICATION)( + IN SEC_THREAD_START StartFunction, + IN PVOID Parameter, + IN ULONG NotificationType, + IN ULONG NotificationClass, + IN ULONG NotificationFlags, + IN ULONG IntervalMinutes, + IN OPTIONAL HANDLE WaitEvent + ); + + +typedef NTSTATUS +(NTAPI LSA_CANCEL_NOTIFICATION)( + IN HANDLE NotifyHandle + ); + +typedef NTSTATUS +(NTAPI LSA_MAP_BUFFER)( + IN PSecBuffer InputBuffer, + OUT PSecBuffer OutputBuffer + ); + +typedef NTSTATUS +(NTAPI LSA_CREATE_TOKEN) ( + IN PLUID LogonId, + IN PTOKEN_SOURCE TokenSource, + IN SECURITY_LOGON_TYPE LogonType, + IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, + IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType, + IN PVOID TokenInformation, + IN PTOKEN_GROUPS TokenGroups, + IN PUNICODE_STRING AccountName, + IN PUNICODE_STRING AuthorityName, + IN PUNICODE_STRING Workstation, + IN PUNICODE_STRING ProfilePath, + OUT PHANDLE Token, + OUT PNTSTATUS SubStatus + ); + +typedef enum _SECPKG_SESSIONINFO_TYPE { + SecSessionPrimaryCred // SessionInformation is SECPKG_PRIMARY_CRED +} SECPKG_SESSIONINFO_TYPE; + +typedef NTSTATUS +(NTAPI LSA_CREATE_TOKEN_EX) ( + IN PLUID LogonId, + IN PTOKEN_SOURCE TokenSource, + IN SECURITY_LOGON_TYPE LogonType, + IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, + IN LSA_TOKEN_INFORMATION_TYPE TokenInformationType, + IN PVOID TokenInformation, + IN PTOKEN_GROUPS TokenGroups, + IN PUNICODE_STRING Workstation, + IN PUNICODE_STRING ProfilePath, + IN PVOID SessionInformation, + IN SECPKG_SESSIONINFO_TYPE SessionInformationType, + OUT PHANDLE Token, + OUT PNTSTATUS SubStatus + ); + +typedef VOID +(NTAPI LSA_AUDIT_LOGON) ( + IN NTSTATUS Status, + IN NTSTATUS SubStatus, + IN PUNICODE_STRING AccountName, + IN PUNICODE_STRING AuthenticatingAuthority, + IN PUNICODE_STRING WorkstationName, + IN OPTIONAL PSID UserSid, + IN SECURITY_LOGON_TYPE LogonType, + IN PTOKEN_SOURCE TokenSource, + IN PLUID LogonId + ); + +typedef NTSTATUS +(NTAPI LSA_CALL_PACKAGE) ( + IN PUNICODE_STRING AuthenticationPackage, + IN PVOID ProtocolSubmitBuffer, + IN ULONG SubmitBufferLength, + OUT PVOID *ProtocolReturnBuffer, + OUT PULONG ReturnBufferLength, + OUT PNTSTATUS ProtocolStatus + ); + +typedef NTSTATUS +(NTAPI LSA_CALL_PACKAGEEX) ( + IN PUNICODE_STRING AuthenticationPackage, + IN PVOID ClientBufferBase, + IN PVOID ProtocolSubmitBuffer, + IN ULONG SubmitBufferLength, + OUT PVOID *ProtocolReturnBuffer, + OUT PULONG ReturnBufferLength, + OUT PNTSTATUS ProtocolStatus + ); + +typedef NTSTATUS +(NTAPI LSA_CALL_PACKAGE_PASSTHROUGH) ( + IN PUNICODE_STRING AuthenticationPackage, + IN PVOID ClientBufferBase, + IN PVOID ProtocolSubmitBuffer, + IN ULONG SubmitBufferLength, + OUT PVOID *ProtocolReturnBuffer, + OUT PULONG ReturnBufferLength, + OUT PNTSTATUS ProtocolStatus + ); + +typedef BOOLEAN +(NTAPI LSA_GET_CALL_INFO) ( + OUT PSECPKG_CALL_INFO Info + ); + +typedef PVOID +(NTAPI LSA_CREATE_SHARED_MEMORY)( + ULONG MaxSize, + ULONG InitialSize + ); + +typedef PVOID +(NTAPI LSA_ALLOCATE_SHARED_MEMORY)( + PVOID SharedMem, + ULONG Size + ); + +typedef VOID +(NTAPI LSA_FREE_SHARED_MEMORY)( + PVOID SharedMem, + PVOID Memory + ); + +typedef BOOLEAN +(NTAPI LSA_DELETE_SHARED_MEMORY)( + PVOID SharedMem + ); + +// +// Account Access +// + +typedef enum _SECPKG_NAME_TYPE { + SecNameSamCompatible, + SecNameAlternateId, + SecNameFlat, + SecNameDN, + SecNameSPN +} SECPKG_NAME_TYPE; + +typedef NTSTATUS +(NTAPI LSA_OPEN_SAM_USER)( + PSECURITY_STRING Name, + SECPKG_NAME_TYPE NameType, + PSECURITY_STRING Prefix, + BOOLEAN AllowGuest, + ULONG Reserved, + PVOID * UserHandle + ); + +typedef NTSTATUS +(NTAPI LSA_GET_USER_CREDENTIALS)( + PVOID UserHandle, + PVOID * PrimaryCreds, + PULONG PrimaryCredsSize, + PVOID * SupplementalCreds, + PULONG SupplementalCredsSize + ); + +typedef NTSTATUS +(NTAPI LSA_GET_USER_AUTH_DATA)( + PVOID UserHandle, + PUCHAR * UserAuthData, + PULONG UserAuthDataSize + ); + +typedef NTSTATUS +(NTAPI LSA_CLOSE_SAM_USER)( + PVOID UserHandle + ); + +typedef NTSTATUS +(NTAPI LSA_GET_AUTH_DATA_FOR_USER)( + PSECURITY_STRING Name, + SECPKG_NAME_TYPE NameType, + PSECURITY_STRING Prefix, + PUCHAR * UserAuthData, + PULONG UserAuthDataSize, + PUNICODE_STRING UserFlatName + ); + +typedef NTSTATUS +(NTAPI LSA_CONVERT_AUTH_DATA_TO_TOKEN)( + IN PVOID UserAuthData, + IN ULONG UserAuthDataSize, + IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, + IN PTOKEN_SOURCE TokenSource, + IN SECURITY_LOGON_TYPE LogonType, + IN PUNICODE_STRING AuthorityName, + OUT PHANDLE Token, + OUT PLUID LogonId, + OUT PUNICODE_STRING AccountName, + OUT PNTSTATUS SubStatus + ); + +typedef NTSTATUS +(NTAPI LSA_CRACK_SINGLE_NAME)( + IN ULONG FormatOffered, + IN BOOLEAN PerformAtGC, + IN PUNICODE_STRING NameInput, + IN PUNICODE_STRING Prefix OPTIONAL, + IN ULONG RequestedFormat, + OUT PUNICODE_STRING CrackedName, + OUT PUNICODE_STRING DnsDomainName, + OUT PULONG SubStatus + ); + +typedef NTSTATUS +(NTAPI LSA_AUDIT_ACCOUNT_LOGON)( + IN ULONG AuditId, + IN BOOLEAN Success, + IN PUNICODE_STRING Source, + IN PUNICODE_STRING ClientName, + IN PUNICODE_STRING MappedName, + IN NTSTATUS Status + ); + + +typedef NTSTATUS +(NTAPI LSA_CLIENT_CALLBACK)( + __in PCHAR Callback, + __in ULONG_PTR Argument1, + __in ULONG_PTR Argument2, + __in PSecBuffer Input, + __out PSecBuffer Output + ); + +typedef +NTSTATUS +(NTAPI LSA_REGISTER_CALLBACK)( + ULONG CallbackId, + PLSA_CALLBACK_FUNCTION Callback + ); + +#define NOTIFIER_FLAG_NEW_THREAD 0x00000001 +#define NOTIFIER_FLAG_ONE_SHOT 0x00000002 +#define NOTIFIER_FLAG_SECONDS 0x80000000 + +#define NOTIFIER_TYPE_INTERVAL 1 +#define NOTIFIER_TYPE_HANDLE_WAIT 2 +#define NOTIFIER_TYPE_STATE_CHANGE 3 +#define NOTIFIER_TYPE_NOTIFY_EVENT 4 +#define NOTIFIER_TYPE_IMMEDIATE 16 + +#define NOTIFY_CLASS_PACKAGE_CHANGE 1 +#define NOTIFY_CLASS_ROLE_CHANGE 2 +#define NOTIFY_CLASS_DOMAIN_CHANGE 3 +#define NOTIFY_CLASS_REGISTRY_CHANGE 4 + +typedef struct _SECPKG_EVENT_PACKAGE_CHANGE { + ULONG ChangeType; + LSA_SEC_HANDLE PackageId; + SECURITY_STRING PackageName; +} SECPKG_EVENT_PACKAGE_CHANGE, * PSECPKG_EVENT_PACKAGE_CHANGE; + +#define SECPKG_PACKAGE_CHANGE_LOAD 0 +#define SECPKG_PACKAGE_CHANGE_UNLOAD 1 +#define SECPKG_PACKAGE_CHANGE_SELECT 2 + +typedef struct _SECPKG_EVENT_ROLE_CHANGE { + ULONG PreviousRole; + ULONG NewRole; +} SECPKG_EVENT_ROLE_CHANGE, * PSECPKG_EVENT_ROLE_CHANGE; + +typedef struct _SECPKG_PARAMETERS SECPKG_EVENT_DOMAIN_CHANGE; +typedef struct _SECPKG_PARAMETERS * PSECPKG_EVENT_DOMAIN_CHANGE; + + +typedef struct _SECPKG_EVENT_NOTIFY { + ULONG EventClass; + ULONG Reserved; + ULONG EventDataSize; + PVOID EventData; + PVOID PackageParameter; +} SECPKG_EVENT_NOTIFY, *PSECPKG_EVENT_NOTIFY; + + +typedef +NTSTATUS +(NTAPI LSA_UPDATE_PRIMARY_CREDENTIALS)( + IN PSECPKG_PRIMARY_CRED PrimaryCredentials, + IN OPTIONAL PSECPKG_SUPPLEMENTAL_CRED_ARRAY Credentials + ); + +typedef +VOID +(NTAPI LSA_PROTECT_MEMORY)( + IN PVOID Buffer, + IN ULONG BufferSize + ); + +typedef +NTSTATUS +(NTAPI LSA_OPEN_TOKEN_BY_LOGON_ID)( + IN PLUID LogonId, + OUT HANDLE *RetTokenHandle + ); + +typedef +NTSTATUS +(NTAPI LSA_EXPAND_AUTH_DATA_FOR_DOMAIN)( + IN PUCHAR UserAuthData, + IN ULONG UserAuthDataSize, + IN PVOID Reserved, + OUT PUCHAR * ExpandedAuthData, + OUT PULONG ExpandedAuthDataSize + ); + +typedef LSA_IMPERSONATE_CLIENT * PLSA_IMPERSONATE_CLIENT; +typedef LSA_UNLOAD_PACKAGE * PLSA_UNLOAD_PACKAGE; +typedef LSA_DUPLICATE_HANDLE * PLSA_DUPLICATE_HANDLE; +typedef LSA_SAVE_SUPPLEMENTAL_CREDENTIALS * PLSA_SAVE_SUPPLEMENTAL_CREDENTIALS; +typedef LSA_CREATE_THREAD * PLSA_CREATE_THREAD; +typedef LSA_GET_CLIENT_INFO * PLSA_GET_CLIENT_INFO; +typedef LSA_REGISTER_NOTIFICATION * PLSA_REGISTER_NOTIFICATION; +typedef LSA_CANCEL_NOTIFICATION * PLSA_CANCEL_NOTIFICATION; +typedef LSA_MAP_BUFFER * PLSA_MAP_BUFFER; +typedef LSA_CREATE_TOKEN * PLSA_CREATE_TOKEN; +typedef LSA_AUDIT_LOGON * PLSA_AUDIT_LOGON; +typedef LSA_CALL_PACKAGE * PLSA_CALL_PACKAGE; +typedef LSA_CALL_PACKAGEEX * PLSA_CALL_PACKAGEEX; +typedef LSA_GET_CALL_INFO * PLSA_GET_CALL_INFO; +typedef LSA_CREATE_SHARED_MEMORY * PLSA_CREATE_SHARED_MEMORY; +typedef LSA_ALLOCATE_SHARED_MEMORY * PLSA_ALLOCATE_SHARED_MEMORY; +typedef LSA_FREE_SHARED_MEMORY * PLSA_FREE_SHARED_MEMORY; +typedef LSA_DELETE_SHARED_MEMORY * PLSA_DELETE_SHARED_MEMORY; +typedef LSA_OPEN_SAM_USER * PLSA_OPEN_SAM_USER; +typedef LSA_GET_USER_CREDENTIALS * PLSA_GET_USER_CREDENTIALS; +typedef LSA_GET_USER_AUTH_DATA * PLSA_GET_USER_AUTH_DATA; +typedef LSA_CLOSE_SAM_USER * PLSA_CLOSE_SAM_USER; +typedef LSA_CONVERT_AUTH_DATA_TO_TOKEN * PLSA_CONVERT_AUTH_DATA_TO_TOKEN; +typedef LSA_CLIENT_CALLBACK * PLSA_CLIENT_CALLBACK; +typedef LSA_REGISTER_CALLBACK * PLSA_REGISTER_CALLBACK; +typedef LSA_UPDATE_PRIMARY_CREDENTIALS * PLSA_UPDATE_PRIMARY_CREDENTIALS; +typedef LSA_GET_AUTH_DATA_FOR_USER * PLSA_GET_AUTH_DATA_FOR_USER; +typedef LSA_CRACK_SINGLE_NAME * PLSA_CRACK_SINGLE_NAME; +typedef LSA_AUDIT_ACCOUNT_LOGON * PLSA_AUDIT_ACCOUNT_LOGON; +typedef LSA_CALL_PACKAGE_PASSTHROUGH * PLSA_CALL_PACKAGE_PASSTHROUGH; +typedef LSA_PROTECT_MEMORY * PLSA_PROTECT_MEMORY; +typedef LSA_OPEN_TOKEN_BY_LOGON_ID * PLSA_OPEN_TOKEN_BY_LOGON_ID; +typedef LSA_EXPAND_AUTH_DATA_FOR_DOMAIN * PLSA_EXPAND_AUTH_DATA_FOR_DOMAIN; +typedef LSA_CREATE_TOKEN_EX * PLSA_CREATE_TOKEN_EX; + +#ifdef _WINCRED_H_ + +// +// When passing a credential around, the CredentialBlob field is encrypted. +// This structure describes this encrypted form. +// +// +#ifndef _ENCRYPTED_CREDENTIAL_DEFINED +#define _ENCRYPTED_CREDENTIAL_DEFINED + +typedef struct _ENCRYPTED_CREDENTIALW { + + // + // The credential + // + // The CredentialBlob field points to the encrypted credential + // The CredentialBlobSize field is the length (in bytes) of the encrypted credential + // + + CREDENTIALW Cred; + + // + // The size in bytes of the clear text credential blob + // + + ULONG ClearCredentialBlobSize; +} ENCRYPTED_CREDENTIALW, *PENCRYPTED_CREDENTIALW; +#endif // _ENCRYPTED_CREDENTIAL_DEFINED + +// +// Values for CredFlags parameter +// + +#define CREDP_FLAGS_IN_PROCESS 0x01 // Caller is in-process. Password data may be returned +#define CREDP_FLAGS_USE_MIDL_HEAP 0x02 // Allocated buffer should use MIDL_user_allocte +#define CREDP_FLAGS_DONT_CACHE_TI 0x04 // TargetInformation shouldn't be cached for CredGetTargetInfo +#define CREDP_FLAGS_CLEAR_PASSWORD 0x08 // Credential blob is passed in in-the-clear +#define CREDP_FLAGS_USER_ENCRYPTED_PASSWORD 0x10 // Credential blob is passed protected by RtlEncryptMemory +#define CREDP_FLAGS_TRUSTED_CALLER 0x20 // Caller is a trusted process (eg. logon process). + +// +// Possible forms of the username returned from CredMan +// + +typedef enum _CredParsedUserNameType +{ + parsedUsernameInvalid = 0, + parsedUsernameUpn, + parsedUsernameNt4Style, + parsedUsernameCertificate, + parsedUsernameNonQualified +} CredParsedUserNameType; + + +typedef NTSTATUS +(NTAPI CredReadFn) ( + IN PLUID LogonId, + IN ULONG CredFlags, + IN LPWSTR TargetName, + IN ULONG Type, + IN ULONG Flags, + OUT PENCRYPTED_CREDENTIALW *Credential + ); + +typedef NTSTATUS +(NTAPI CredReadDomainCredentialsFn) ( + IN PLUID LogonId, + IN ULONG CredFlags, + IN PCREDENTIAL_TARGET_INFORMATIONW TargetInfo, + IN ULONG Flags, + OUT PULONG Count, + OUT PENCRYPTED_CREDENTIALW **Credential + ); + +typedef VOID +(NTAPI CredFreeCredentialsFn) ( + IN ULONG Count, + IN PENCRYPTED_CREDENTIALW *Credentials OPTIONAL + ); + +typedef NTSTATUS +(NTAPI CredWriteFn) ( + IN PLUID LogonId, + IN ULONG CredFlags, + IN PENCRYPTED_CREDENTIALW Credential, + IN ULONG Flags + ); + +typedef NTSTATUS +(NTAPI CrediUnmarshalandDecodeStringFn)( + IN LPWSTR MarshaledString, + OUT LPBYTE *Blob, + OUT ULONG *BlobSize, + OUT BOOLEAN *IsFailureFatal + ); + + +NTSTATUS +CredMarshalTargetInfo ( + __in PCREDENTIAL_TARGET_INFORMATIONW InTargetInfo, + __deref_out PUSHORT *Buffer, + __out PULONG BufferSize + ); + +NTSTATUS +CredUnmarshalTargetInfo ( + __in_bcount(BufferSize) PUSHORT Buffer, + __in ULONG BufferSize, + __out_opt PCREDENTIAL_TARGET_INFORMATIONW *RetTargetInfo, + __out_opt PULONG RetActualSize + ); + +// Number of bytes consumed by the trailing size ULONG +#define CRED_MARSHALED_TI_SIZE_SIZE 12 + +NTSTATUS +CredParseUserNameWithType ( + __inout LPWSTR szParseName, + __out_opt PUNICODE_STRING pUserName, + __out_opt PUNICODE_STRING pDomainName, + __out CredParsedUserNameType * pParseType + ); + +#endif // _WINCRED_H_ + + +// +// Pure 32-bit versions of credential structures for packages +// running wow64: +// + +typedef struct _SEC_WINNT_AUTH_IDENTITY32 { + ULONG User; + ULONG UserLength; + ULONG Domain; + ULONG DomainLength; + ULONG Password; + ULONG PasswordLength; + ULONG Flags; +} SEC_WINNT_AUTH_IDENTITY32, * PSEC_WINNT_AUTH_IDENTITY32; + +typedef struct _SEC_WINNT_AUTH_IDENTITY_EX32 { + ULONG Version; + ULONG Length; + ULONG User; + ULONG UserLength; + ULONG Domain; + ULONG DomainLength; + ULONG Password; + ULONG PasswordLength; + ULONG Flags; + ULONG PackageList; + ULONG PackageListLength; +} SEC_WINNT_AUTH_IDENTITY_EX32, * PSEC_WINNT_AUTH_IDENTITY_EX32; + +// Functions provided by the SPM to the packages: +typedef struct _LSA_SECPKG_FUNCTION_TABLE { + PLSA_CREATE_LOGON_SESSION CreateLogonSession; + PLSA_DELETE_LOGON_SESSION DeleteLogonSession; + PLSA_ADD_CREDENTIAL AddCredential; + PLSA_GET_CREDENTIALS GetCredentials; + PLSA_DELETE_CREDENTIAL DeleteCredential; + PLSA_ALLOCATE_LSA_HEAP AllocateLsaHeap; + PLSA_FREE_LSA_HEAP FreeLsaHeap; + PLSA_ALLOCATE_CLIENT_BUFFER AllocateClientBuffer; + PLSA_FREE_CLIENT_BUFFER FreeClientBuffer; + PLSA_COPY_TO_CLIENT_BUFFER CopyToClientBuffer; + PLSA_COPY_FROM_CLIENT_BUFFER CopyFromClientBuffer; + PLSA_IMPERSONATE_CLIENT ImpersonateClient; + PLSA_UNLOAD_PACKAGE UnloadPackage; + PLSA_DUPLICATE_HANDLE DuplicateHandle; + PLSA_SAVE_SUPPLEMENTAL_CREDENTIALS SaveSupplementalCredentials; + PLSA_CREATE_THREAD CreateThread; + PLSA_GET_CLIENT_INFO GetClientInfo; + PLSA_REGISTER_NOTIFICATION RegisterNotification; + PLSA_CANCEL_NOTIFICATION CancelNotification; + PLSA_MAP_BUFFER MapBuffer; + PLSA_CREATE_TOKEN CreateToken; + PLSA_AUDIT_LOGON AuditLogon; + PLSA_CALL_PACKAGE CallPackage; + PLSA_FREE_LSA_HEAP FreeReturnBuffer; + PLSA_GET_CALL_INFO GetCallInfo; + PLSA_CALL_PACKAGEEX CallPackageEx; + PLSA_CREATE_SHARED_MEMORY CreateSharedMemory; + PLSA_ALLOCATE_SHARED_MEMORY AllocateSharedMemory; + PLSA_FREE_SHARED_MEMORY FreeSharedMemory; + PLSA_DELETE_SHARED_MEMORY DeleteSharedMemory; + PLSA_OPEN_SAM_USER OpenSamUser; + PLSA_GET_USER_CREDENTIALS GetUserCredentials; + PLSA_GET_USER_AUTH_DATA GetUserAuthData; + PLSA_CLOSE_SAM_USER CloseSamUser; + PLSA_CONVERT_AUTH_DATA_TO_TOKEN ConvertAuthDataToToken; + PLSA_CLIENT_CALLBACK ClientCallback; + PLSA_UPDATE_PRIMARY_CREDENTIALS UpdateCredentials; + PLSA_GET_AUTH_DATA_FOR_USER GetAuthDataForUser; + PLSA_CRACK_SINGLE_NAME CrackSingleName; + PLSA_AUDIT_ACCOUNT_LOGON AuditAccountLogon; + PLSA_CALL_PACKAGE_PASSTHROUGH CallPackagePassthrough; +#ifdef _WINCRED_H_ + CredReadFn *CrediRead; + CredReadDomainCredentialsFn *CrediReadDomainCredentials; + CredFreeCredentialsFn *CrediFreeCredentials; +#else // _WINCRED_H_ + PLSA_PROTECT_MEMORY DummyFunction1; + PLSA_PROTECT_MEMORY DummyFunction2; + PLSA_PROTECT_MEMORY DummyFunction3; +#endif // _WINCRED_H_ + PLSA_PROTECT_MEMORY LsaProtectMemory; + PLSA_PROTECT_MEMORY LsaUnprotectMemory; + PLSA_OPEN_TOKEN_BY_LOGON_ID OpenTokenByLogonId; + PLSA_EXPAND_AUTH_DATA_FOR_DOMAIN ExpandAuthDataForDomain; + PLSA_ALLOCATE_PRIVATE_HEAP AllocatePrivateHeap; + PLSA_FREE_PRIVATE_HEAP FreePrivateHeap; + PLSA_CREATE_TOKEN_EX CreateTokenEx; +#ifdef _WINCRED_H_ + CredWriteFn *CrediWrite; + CrediUnmarshalandDecodeStringFn *CrediUnmarshalandDecodeString; +#else // _WINCRED_H_ + PLSA_PROTECT_MEMORY DummyFunction4; + PLSA_PROTECT_MEMORY DummyFunction5; +#endif // _WINCRED_H_ +} LSA_SECPKG_FUNCTION_TABLE, *PLSA_SECPKG_FUNCTION_TABLE; + + +typedef +PVOID +(NTAPI LSA_LOCATE_PKG_BY_ID)( + __in ULONG PackgeId + ); + +typedef LSA_LOCATE_PKG_BY_ID * PLSA_LOCATE_PKG_BY_ID; + +typedef struct _SECPKG_DLL_FUNCTIONS { + PLSA_ALLOCATE_LSA_HEAP AllocateHeap; + PLSA_FREE_LSA_HEAP FreeHeap; + PLSA_REGISTER_CALLBACK RegisterCallback; + PLSA_LOCATE_PKG_BY_ID LocatePackageById; +} SECPKG_DLL_FUNCTIONS, * PSECPKG_DLL_FUNCTIONS; + + +// +// The following prototypes are to functions that will be called only while +// in the Security Package Manager context. +// + +typedef NTSTATUS +(NTAPI SpInitializeFn)( + IN ULONG_PTR PackageId, + IN PSECPKG_PARAMETERS Parameters, + IN PLSA_SECPKG_FUNCTION_TABLE FunctionTable + ); + +typedef NTSTATUS +(NTAPI SpShutdownFn)( + VOID + ); + +typedef NTSTATUS +(NTAPI SpGetInfoFn)( + OUT PSecPkgInfo PackageInfo + ); + +typedef NTSTATUS +(NTAPI SpGetExtendedInformationFn)( + IN SECPKG_EXTENDED_INFORMATION_CLASS Class, + OUT PSECPKG_EXTENDED_INFORMATION * ppInformation + ); + +typedef NTSTATUS +(NTAPI SpSetExtendedInformationFn)( + IN SECPKG_EXTENDED_INFORMATION_CLASS Class, + IN PSECPKG_EXTENDED_INFORMATION Info + ); + +typedef NTSTATUS +(LSA_AP_LOGON_USER_EX2) ( + __in PLSA_CLIENT_REQUEST ClientRequest, + __in SECURITY_LOGON_TYPE LogonType, + __in_bcount(SubmitBufferSize) PVOID ProtocolSubmitBuffer, + __in PVOID ClientBufferBase, + __in ULONG SubmitBufferSize, + __deref_out_bcount(*ProfileBufferSize) PVOID *ProfileBuffer, + __out PULONG ProfileBufferSize, + __out PLUID LogonId, + __out PNTSTATUS SubStatus, + __out PLSA_TOKEN_INFORMATION_TYPE TokenInformationType, + __deref_out PVOID *TokenInformation, + __out PUNICODE_STRING *AccountName, + __out PUNICODE_STRING *AuthenticatingAuthority, + __out PUNICODE_STRING *MachineName, + __out PSECPKG_PRIMARY_CRED PrimaryCredentials, + __deref_out PSECPKG_SUPPLEMENTAL_CRED_ARRAY * SupplementalCredentials + ); + +typedef LSA_AP_LOGON_USER_EX2 *PLSA_AP_LOGON_USER_EX2; +#define LSA_AP_NAME_LOGON_USER_EX2 "LsaApLogonUserEx2\0" + +typedef NTSTATUS +(NTAPI SpAcceptCredentialsFn)( + IN SECURITY_LOGON_TYPE LogonType, + IN PUNICODE_STRING AccountName, + IN PSECPKG_PRIMARY_CRED PrimaryCredentials, + IN PSECPKG_SUPPLEMENTAL_CRED SupplementalCredentials + ); +#define SP_ACCEPT_CREDENTIALS_NAME "SpAcceptCredentials\0" + +typedef NTSTATUS +(NTAPI SpAcquireCredentialsHandleFn)( + IN OPTIONAL PUNICODE_STRING PrincipalName, + IN ULONG CredentialUseFlags, + IN OPTIONAL PLUID LogonId, + IN PVOID AuthorizationData, + IN PVOID GetKeyFunciton, + IN PVOID GetKeyArgument, + OUT PLSA_SEC_HANDLE CredentialHandle, + OUT PTimeStamp ExpirationTime + ); + +typedef NTSTATUS +(NTAPI SpFreeCredentialsHandleFn)( + IN LSA_SEC_HANDLE CredentialHandle + ); + +typedef NTSTATUS +(NTAPI SpQueryCredentialsAttributesFn)( + IN LSA_SEC_HANDLE CredentialHandle, + IN ULONG CredentialAttribute, + IN OUT PVOID Buffer + ); + +typedef NTSTATUS +(NTAPI SpSetCredentialsAttributesFn)( + IN LSA_SEC_HANDLE CredentialHandle, + IN ULONG CredentialAttribute, + IN PVOID Buffer, + IN ULONG BufferSize ); + +typedef NTSTATUS +(NTAPI SpAddCredentialsFn)( + IN LSA_SEC_HANDLE CredentialHandle, + IN OPTIONAL PUNICODE_STRING PrincipalName, + IN PUNICODE_STRING Package, + IN ULONG CredentialUseFlags, + IN PVOID AuthorizationData, + IN PVOID GetKeyFunciton, + IN PVOID GetKeyArgument, + OUT PTimeStamp ExpirationTime + ); + +typedef NTSTATUS +(NTAPI SpSaveCredentialsFn)( + IN LSA_SEC_HANDLE CredentialHandle, + IN PSecBuffer Credentials); + +typedef NTSTATUS +(NTAPI SpGetCredentialsFn)( + IN LSA_SEC_HANDLE CredentialHandle, + IN OUT PSecBuffer Credentials + ); + +typedef NTSTATUS +(NTAPI SpDeleteCredentialsFn)( + IN LSA_SEC_HANDLE CredentialHandle, + IN PSecBuffer Key + ); + +typedef NTSTATUS +(NTAPI SpInitLsaModeContextFn)( + IN OPTIONAL LSA_SEC_HANDLE CredentialHandle, + IN OPTIONAL LSA_SEC_HANDLE ContextHandle, + IN OPTIONAL PUNICODE_STRING TargetName, + IN ULONG ContextRequirements, + IN ULONG TargetDataRep, + IN PSecBufferDesc InputBuffers, + OUT PLSA_SEC_HANDLE NewContextHandle, + IN OUT PSecBufferDesc OutputBuffers, + OUT PULONG ContextAttributes, + OUT PTimeStamp ExpirationTime, + OUT PBOOLEAN MappedContext, + OUT PSecBuffer ContextData + ); + + + + +typedef NTSTATUS +(NTAPI SpDeleteContextFn)( + IN LSA_SEC_HANDLE ContextHandle + ); + +typedef NTSTATUS +(NTAPI SpApplyControlTokenFn)( + IN LSA_SEC_HANDLE ContextHandle, + IN PSecBufferDesc ControlToken); + + +typedef NTSTATUS +(NTAPI SpAcceptLsaModeContextFn)( + IN OPTIONAL LSA_SEC_HANDLE CredentialHandle, + IN OPTIONAL LSA_SEC_HANDLE ContextHandle, + IN PSecBufferDesc InputBuffer, + IN ULONG ContextRequirements, + IN ULONG TargetDataRep, + OUT PLSA_SEC_HANDLE NewContextHandle, + OUT PSecBufferDesc OutputBuffer, + OUT PULONG ContextAttributes, + OUT PTimeStamp ExpirationTime, + OUT PBOOLEAN MappedContext, + OUT PSecBuffer ContextData + ); + + + + +typedef NTSTATUS +(NTAPI SpGetUserInfoFn)( + IN PLUID LogonId, + IN ULONG Flags, + OUT PSecurityUserData * UserData + ); + +typedef NTSTATUS +(NTAPI SpQueryContextAttributesFn)( + IN LSA_SEC_HANDLE ContextHandle, + IN ULONG ContextAttribute, + IN OUT PVOID Buffer); + +typedef NTSTATUS +(NTAPI SpSetContextAttributesFn)( + IN LSA_SEC_HANDLE ContextHandle, + IN ULONG ContextAttribute, + IN PVOID Buffer, + IN ULONG BufferSize ); + +typedef NTSTATUS +(NTAPI SpChangeAccountPasswordFn)( + __in PUNICODE_STRING pDomainName, + __in PUNICODE_STRING pAccountName, + __in PUNICODE_STRING pOldPassword, + __in PUNICODE_STRING pNewPassword, + __in BOOLEAN Impersonating, + __inout PSecBufferDesc pOutput + ); + +typedef NTSTATUS +(NTAPI SpQueryMetaDataFn)( + __in_opt LSA_SEC_HANDLE CredentialHandle, + __in_opt PUNICODE_STRING TargetName, + __in ULONG ContextRequirements, + __out PULONG MetaDataLength, + __deref_out_bcount(*MetaDataLength) PUCHAR* MetaData, + __inout PLSA_SEC_HANDLE ContextHandle + ); + +typedef NTSTATUS +(NTAPI SpExchangeMetaDataFn)( + __in_opt LSA_SEC_HANDLE CredentialHandle, + __in_opt PUNICODE_STRING TargetName, + __in ULONG ContextRequirements, + __in ULONG MetaDataLength, + __in_bcount(MetaDataLength) PUCHAR MetaData, + __inout PLSA_SEC_HANDLE ContextHandle + ); + +typedef NTSTATUS +(NTAPI SpGetCredUIContextFn)( + __in LSA_SEC_HANDLE ContextHandle, + __in GUID* CredType, + __out PULONG FlatCredUIContextLength, + __deref_out_bcount(*FlatCredUIContextLength) PUCHAR* FlatCredUIContext + ); + +typedef NTSTATUS +(NTAPI SpUpdateCredentialsFn)( + __in LSA_SEC_HANDLE ContextHandle, + __in GUID* CredType, + __in ULONG FlatCredUIContextLength, + __in_bcount(FlatCredUIContextLength) PUCHAR FlatCredUIContext + ); + +typedef NTSTATUS +(NTAPI SpValidateTargetInfoFn) ( + __in_opt PLSA_CLIENT_REQUEST ClientRequest, + __in_bcount(SubmitBufferLength) PVOID ProtocolSubmitBuffer, + __in PVOID ClientBufferBase, + __in ULONG SubmitBufferLength, + __in PSECPKG_TARGETINFO TargetInfo + ); + +typedef struct _SECPKG_FUNCTION_TABLE { + PLSA_AP_INITIALIZE_PACKAGE InitializePackage; + PLSA_AP_LOGON_USER LogonUser; + PLSA_AP_CALL_PACKAGE CallPackage; + PLSA_AP_LOGON_TERMINATED LogonTerminated; + PLSA_AP_CALL_PACKAGE_UNTRUSTED CallPackageUntrusted; + PLSA_AP_CALL_PACKAGE_PASSTHROUGH CallPackagePassthrough; + PLSA_AP_LOGON_USER_EX LogonUserEx; + PLSA_AP_LOGON_USER_EX2 LogonUserEx2; + SpInitializeFn * Initialize; + SpShutdownFn * Shutdown; + SpGetInfoFn * GetInfo; + SpAcceptCredentialsFn * AcceptCredentials; + SpAcquireCredentialsHandleFn * AcquireCredentialsHandle; + SpQueryCredentialsAttributesFn * QueryCredentialsAttributes; + SpFreeCredentialsHandleFn * FreeCredentialsHandle; + SpSaveCredentialsFn * SaveCredentials; + SpGetCredentialsFn * GetCredentials; + SpDeleteCredentialsFn * DeleteCredentials; + SpInitLsaModeContextFn * InitLsaModeContext; + SpAcceptLsaModeContextFn * AcceptLsaModeContext; + SpDeleteContextFn * DeleteContext; + SpApplyControlTokenFn * ApplyControlToken; + SpGetUserInfoFn * GetUserInfo; + SpGetExtendedInformationFn * GetExtendedInformation; + SpQueryContextAttributesFn * QueryContextAttributes; + SpAddCredentialsFn * AddCredentials; + SpSetExtendedInformationFn * SetExtendedInformation; + SpSetContextAttributesFn * SetContextAttributes; + SpSetCredentialsAttributesFn * SetCredentialsAttributes; + SpChangeAccountPasswordFn * ChangeAccountPassword; + SpQueryMetaDataFn* QueryMetaData; + SpExchangeMetaDataFn* ExchangeMetaData; + SpGetCredUIContextFn* GetCredUIContext; + SpUpdateCredentialsFn* UpdateCredentials; + SpValidateTargetInfoFn* ValidateTargetInfo; +} SECPKG_FUNCTION_TABLE, *PSECPKG_FUNCTION_TABLE; + +// +// The following prototypes are to functions that will be called while in the +// context of a user process that is using the functions through the security +// DLL. +// +typedef NTSTATUS +(NTAPI SpInstanceInitFn)( + IN ULONG Version, + IN PSECPKG_DLL_FUNCTIONS FunctionTable, + OUT PVOID * UserFunctions + ); + +typedef NTSTATUS +(NTAPI SpInitUserModeContextFn)( + IN LSA_SEC_HANDLE ContextHandle, + IN PSecBuffer PackedContext + ); + +typedef NTSTATUS +(NTAPI SpMakeSignatureFn)( + IN LSA_SEC_HANDLE ContextHandle, + IN ULONG QualityOfProtection, + IN PSecBufferDesc MessageBuffers, + IN ULONG MessageSequenceNumber + ); + +typedef NTSTATUS +(NTAPI SpVerifySignatureFn)( + IN LSA_SEC_HANDLE ContextHandle, + IN PSecBufferDesc MessageBuffers, + IN ULONG MessageSequenceNumber, + OUT PULONG QualityOfProtection + ); + +typedef NTSTATUS +(NTAPI SpSealMessageFn)( + IN LSA_SEC_HANDLE ContextHandle, + IN ULONG QualityOfProtection, + IN PSecBufferDesc MessageBuffers, + IN ULONG MessageSequenceNumber + ); + +typedef NTSTATUS +(NTAPI SpUnsealMessageFn)( + IN LSA_SEC_HANDLE ContextHandle, + IN PSecBufferDesc MessageBuffers, + IN ULONG MessageSequenceNumber, + OUT PULONG QualityOfProtection + ); + + +typedef NTSTATUS +(NTAPI SpGetContextTokenFn)( + IN LSA_SEC_HANDLE ContextHandle, + OUT PHANDLE ImpersonationToken + ); + + +typedef NTSTATUS +(NTAPI SpExportSecurityContextFn)( + LSA_SEC_HANDLE phContext, // (in) context to export + ULONG fFlags, // (in) option flags + PSecBuffer pPackedContext, // (out) marshalled context + PHANDLE pToken // (out, optional) token handle for impersonation + ); + +typedef NTSTATUS +(NTAPI SpImportSecurityContextFn)( + PSecBuffer pPackedContext, // (in) marshalled context + HANDLE Token, // (in, optional) handle to token for context + PLSA_SEC_HANDLE phContext // (out) new context handle + ); + + +typedef NTSTATUS +(NTAPI SpCompleteAuthTokenFn)( + IN LSA_SEC_HANDLE ContextHandle, + IN PSecBufferDesc InputBuffer + ); + + +typedef NTSTATUS +(NTAPI SpFormatCredentialsFn)( + IN PSecBuffer Credentials, + OUT PSecBuffer FormattedCredentials + ); + +typedef NTSTATUS +(NTAPI SpMarshallSupplementalCredsFn)( + IN ULONG CredentialSize, + IN PUCHAR Credentials, + OUT PULONG MarshalledCredSize, + OUT PVOID * MarshalledCreds); + +typedef struct _SECPKG_USER_FUNCTION_TABLE { + SpInstanceInitFn * InstanceInit; + SpInitUserModeContextFn * InitUserModeContext; + SpMakeSignatureFn * MakeSignature; + SpVerifySignatureFn * VerifySignature; + SpSealMessageFn * SealMessage; + SpUnsealMessageFn * UnsealMessage; + SpGetContextTokenFn * GetContextToken; + SpQueryContextAttributesFn * QueryContextAttributes; + SpCompleteAuthTokenFn * CompleteAuthToken; + SpDeleteContextFn * DeleteUserModeContext; + SpFormatCredentialsFn * FormatCredentials; + SpMarshallSupplementalCredsFn * MarshallSupplementalCreds; + SpExportSecurityContextFn * ExportContext; + SpImportSecurityContextFn * ImportContext; +} SECPKG_USER_FUNCTION_TABLE, *PSECPKG_USER_FUNCTION_TABLE; + + +typedef NTSTATUS +(SEC_ENTRY * SpLsaModeInitializeFn)( + IN ULONG LsaVersion, + OUT PULONG PackageVersion, + OUT PSECPKG_FUNCTION_TABLE * ppTables, + OUT PULONG pcTables); + +typedef NTSTATUS +(SEC_ENTRY * SpUserModeInitializeFn)( + IN ULONG LsaVersion, + OUT PULONG PackageVersion, + OUT PSECPKG_USER_FUNCTION_TABLE *ppTables, + OUT PULONG pcTables + ); + +#define SECPKG_LSAMODEINIT_NAME "SpLsaModeInitialize" +#define SECPKG_USERMODEINIT_NAME "SpUserModeInitialize" + +// +// Version of the security package interface. +// +// These defines are used for all of the following: +// +// * Passed by the LSA to SpLsaModeInitializeFn to indicate the version of the LSA. +// All packages currently expect the LSA to pass SECPKG_INTERFACE_VERSION. +// +// * Passed by secur32.dll to SpUserModeInitialzeFn to indicate the version of the secur32 DLL. +// All packages currently expect secur32 to pass SECPKG_INTERFACE_VERSION. +// +// * Returned from SpLsaModeInitializeFn to indicate the version of SECPKG_FUNCTION_TABLE. +// SECPKG_INTERFACE_VERSION indicates all fields through SetExtendedInformation are defined (potentially to NULL) +// SECPKG_INTERFACE_VERSION_2 indicates all fields through SetContextAttributes are defined (potentially to NULL) +// SECPKG_INTERFACE_VERSION_3 indicates all fields through SetCredentialsAttributes are defined (potentially to NULL) +// SECPKG_INTERFACE_VERSION_4 indicates all fields through ChangeAccountPassword are defined (potentially to NULL) +// SECPKG_INTERFACE_VERSION_5 indicates all fields through UpdateCredentials are defined (potentially to NULL) +// SECPKG_INTERFACE_VERSION_6 indicates all fields through ValidateTargetInfo are defined (potentially to NULL) +// +// * Returned from SpUserModeInitializeFn to indicate the version of the auth package. +// All packages currently return SECPKG_INTERFACE_VERSION +// + +#define SECPKG_INTERFACE_VERSION 0x00010000 +#define SECPKG_INTERFACE_VERSION_2 0x00020000 +#define SECPKG_INTERFACE_VERSION_3 0x00040000 +#define SECPKG_INTERFACE_VERSION_4 0x00080000 +#define SECPKG_INTERFACE_VERSION_5 0x00100000 +#define SECPKG_INTERFACE_VERSION_6 0x00200000 + +typedef enum _KSEC_CONTEXT_TYPE { + KSecPaged, + KSecNonPaged +} KSEC_CONTEXT_TYPE; + +typedef struct _KSEC_LIST_ENTRY { + LIST_ENTRY List; + LONG RefCount; + ULONG Signature; + PVOID OwningList; + PVOID Reserved; +} KSEC_LIST_ENTRY, * PKSEC_LIST_ENTRY; + +#define KsecInitializeListEntry( Entry, SigValue ) \ + ((PKSEC_LIST_ENTRY) Entry)->List.Flink = ((PKSEC_LIST_ENTRY) Entry)->List.Blink = NULL; \ + ((PKSEC_LIST_ENTRY) Entry)->RefCount = 1; \ + ((PKSEC_LIST_ENTRY) Entry)->Signature = SigValue; \ + ((PKSEC_LIST_ENTRY) Entry)->OwningList = NULL; \ + ((PKSEC_LIST_ENTRY) Entry)->Reserved = NULL; + + + +typedef PVOID +(SEC_ENTRY KSEC_CREATE_CONTEXT_LIST)( + IN KSEC_CONTEXT_TYPE Type + ); + +typedef VOID +(SEC_ENTRY KSEC_INSERT_LIST_ENTRY)( + IN PVOID List, + IN PKSEC_LIST_ENTRY Entry + ); + +typedef NTSTATUS +(SEC_ENTRY KSEC_REFERENCE_LIST_ENTRY)( + IN PKSEC_LIST_ENTRY Entry, + IN ULONG Signature, + IN BOOLEAN RemoveNoRef + ); + +typedef VOID +(SEC_ENTRY KSEC_DEREFERENCE_LIST_ENTRY)( + IN PKSEC_LIST_ENTRY Entry, + OUT BOOLEAN * Delete OPTIONAL + ); + +typedef NTSTATUS +(SEC_ENTRY KSEC_SERIALIZE_WINNT_AUTH_DATA)( + __in PVOID pvAuthData, + __out PULONG Size, + __deref_out PVOID * SerializedData ); + +typedef NTSTATUS +(SEC_ENTRY KSEC_SERIALIZE_SCHANNEL_AUTH_DATA)( + __in PVOID pvAuthData, + __out PULONG Size, + __deref_out PVOID * SerializedData ); + +#ifndef MIDL_PASS + +KSEC_CREATE_CONTEXT_LIST KSecCreateContextList; +KSEC_INSERT_LIST_ENTRY KSecInsertListEntry; +KSEC_REFERENCE_LIST_ENTRY KSecReferenceListEntry; +KSEC_DEREFERENCE_LIST_ENTRY KSecDereferenceListEntry; +KSEC_SERIALIZE_WINNT_AUTH_DATA KSecSerializeWinntAuthData; +KSEC_SERIALIZE_SCHANNEL_AUTH_DATA KSecSerializeSchannelAuthData; + +#endif // not valid for MIDL_PASS + +typedef KSEC_CREATE_CONTEXT_LIST * PKSEC_CREATE_CONTEXT_LIST; +typedef KSEC_INSERT_LIST_ENTRY * PKSEC_INSERT_LIST_ENTRY; +typedef KSEC_REFERENCE_LIST_ENTRY * PKSEC_REFERENCE_LIST_ENTRY; +typedef KSEC_DEREFERENCE_LIST_ENTRY * PKSEC_DEREFERENCE_LIST_ENTRY; +typedef KSEC_SERIALIZE_WINNT_AUTH_DATA * PKSEC_SERIALIZE_WINNT_AUTH_DATA; +typedef KSEC_SERIALIZE_SCHANNEL_AUTH_DATA * PKSEC_SERIALIZE_SCHANNEL_AUTH_DATA; + +typedef PVOID +(SEC_ENTRY KSEC_LOCATE_PKG_BY_ID)( + __in ULONG PackageId + ); + +typedef KSEC_LOCATE_PKG_BY_ID * PKSEC_LOCATE_PKG_BY_ID; + +#ifndef MIDL_PASS + +KSEC_LOCATE_PKG_BY_ID KSecLocatePackageById; + +#endif // not valid for MIDL_PASS + +typedef struct _SECPKG_KERNEL_FUNCTIONS { + PLSA_ALLOCATE_LSA_HEAP AllocateHeap; + PLSA_FREE_LSA_HEAP FreeHeap; + PKSEC_CREATE_CONTEXT_LIST CreateContextList; + PKSEC_INSERT_LIST_ENTRY InsertListEntry; + PKSEC_REFERENCE_LIST_ENTRY ReferenceListEntry; + PKSEC_DEREFERENCE_LIST_ENTRY DereferenceListEntry; + PKSEC_SERIALIZE_WINNT_AUTH_DATA SerializeWinntAuthData; + PKSEC_SERIALIZE_SCHANNEL_AUTH_DATA SerializeSchannelAuthData; + PKSEC_LOCATE_PKG_BY_ID LocatePackageById; +} SECPKG_KERNEL_FUNCTIONS, *PSECPKG_KERNEL_FUNCTIONS; + +typedef NTSTATUS +(NTAPI KspInitPackageFn)( + PSECPKG_KERNEL_FUNCTIONS FunctionTable + ); + +typedef NTSTATUS +(NTAPI KspDeleteContextFn)( + IN LSA_SEC_HANDLE ContextId, + OUT PLSA_SEC_HANDLE LsaContextId + ); + +typedef NTSTATUS +(NTAPI KspInitContextFn)( + IN LSA_SEC_HANDLE ContextId, + IN PSecBuffer ContextData, + OUT PLSA_SEC_HANDLE NewContextId + ); + +typedef NTSTATUS +(NTAPI KspMakeSignatureFn)( + IN LSA_SEC_HANDLE ContextId, + IN ULONG fQOP, + IN OUT PSecBufferDesc Message, + IN ULONG MessageSeqNo + ); + +typedef NTSTATUS +(NTAPI KspVerifySignatureFn)( + IN LSA_SEC_HANDLE ContextId, + IN OUT PSecBufferDesc Message, + IN ULONG MessageSeqNo, + OUT PULONG pfQOP + ); + + +typedef NTSTATUS +(NTAPI KspSealMessageFn)( + IN LSA_SEC_HANDLE ContextId, + IN ULONG fQOP, + IN OUT PSecBufferDesc Message, + IN ULONG MessageSeqNo + ); + +typedef NTSTATUS +(NTAPI KspUnsealMessageFn)( + IN LSA_SEC_HANDLE ContextId, + IN OUT PSecBufferDesc Message, + IN ULONG MessageSeqNo, + OUT PULONG pfQOP + ); + +typedef NTSTATUS +(NTAPI KspGetTokenFn)( + IN LSA_SEC_HANDLE ContextId, + OUT PHANDLE ImpersonationToken, + OUT OPTIONAL PACCESS_TOKEN * RawToken + ); + +typedef NTSTATUS +(NTAPI KspQueryAttributesFn)( + IN LSA_SEC_HANDLE ContextId, + IN ULONG Attribute, + IN OUT PVOID Buffer + ); + +typedef NTSTATUS +(NTAPI KspCompleteTokenFn)( + IN LSA_SEC_HANDLE ContextId, + IN PSecBufferDesc Token + ); + + +typedef NTSTATUS +(NTAPI KspMapHandleFn)( + IN LSA_SEC_HANDLE ContextId, + OUT PLSA_SEC_HANDLE LsaContextId + ); + +typedef NTSTATUS +(NTAPI KspSetPagingModeFn)( + IN BOOLEAN PagingMode + ); + +typedef NTSTATUS +(NTAPI KspSerializeAuthDataFn)( + IN PVOID pvAuthData, + OUT PULONG Size, + OUT PVOID * SerializedData + ); + +typedef struct _SECPKG_KERNEL_FUNCTION_TABLE { + KspInitPackageFn * Initialize; + KspDeleteContextFn * DeleteContext; + KspInitContextFn * InitContext; + KspMapHandleFn * MapHandle; + KspMakeSignatureFn * Sign; + KspVerifySignatureFn * Verify; + KspSealMessageFn * Seal; + KspUnsealMessageFn * Unseal; + KspGetTokenFn * GetToken; + KspQueryAttributesFn * QueryAttributes; + KspCompleteTokenFn * CompleteToken; + SpExportSecurityContextFn * ExportContext; + SpImportSecurityContextFn * ImportContext; + KspSetPagingModeFn * SetPackagePagingMode; + KspSerializeAuthDataFn * SerializeAuthData; +} SECPKG_KERNEL_FUNCTION_TABLE, *PSECPKG_KERNEL_FUNCTION_TABLE; + +SECURITY_STATUS +SEC_ENTRY +KSecRegisterSecurityProvider( + __in PSECURITY_STRING ProviderName, + __in PSECPKG_KERNEL_FUNCTION_TABLE Table + ); + +extern SECPKG_KERNEL_FUNCTIONS KspKernelFunctions; + + +#ifdef __cplusplus +} +#endif + +#endif /* _NTSECPKG_ */ + + diff --git a/utils/EBP.h b/utils/EBP.h new file mode 100644 index 0000000..dbca9e2 --- /dev/null +++ b/utils/EBP.h @@ -0,0 +1,34 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + pshpack8.h + +Abstract: + + This file turns 8 byte packing of structures on. (That is, it disables + automatic alignment of structure fields.) An include file is needed + because various compilers do this in different ways. For Microsoft + compatible compilers, this files uses the push option to the pack pragma + so that the poppack.h include file can restore the previous packing + reliably. + + The file poppack.h is the complement to this file. + +--*/ + +#if ! (defined(lint) || defined(RC_INVOKED)) +#if ( _MSC_VER >= 800 && !defined(_M_I86)) || defined(_PUSHPOP_SUPPORTED) +#pragma warning(disable:4103) +#if !(defined( MIDL_PASS )) || defined( __midl ) +#pragma pack(push,8) +#else +#pragma pack(8) +#endif +#else +#pragma pack(8) +#endif +#endif /* ! (defined(lint) || defined(RC_INVOKED)) */ + diff --git a/utils/EBSSDk.h b/utils/EBSSDk.h new file mode 100644 index 0000000..717d312 --- /dev/null +++ b/utils/EBSSDk.h @@ -0,0 +1,495 @@ +/*++ + +Copyright (C) 1997-1999 Microsoft Corporation + +Module Name: + + dhcpssdk.h + +Abstract: + + Header for writing a DHCP Callout DLL. + +--*/ + +#ifndef _CALLOUT_H_ +#define _CALLOUT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#if _MSC_VER > 1000 +#pragma once +#endif + +// This structure could change any day. This will be accurate only for version 0 -- which +// has to be checked for by any CalloutDLL that is hooking onto the DhcpHandleOptionsHook. + + +typedef DWORD DHCP_IP_ADDRESS; +typedef struct _DHCP_SERVER_OPTIONS { + BYTE *MessageType; + DHCP_IP_ADDRESS UNALIGNED *SubnetMask; + DHCP_IP_ADDRESS UNALIGNED *RequestedAddress; + DWORD UNALIGNED *RequestLeaseTime; + BYTE *OverlayFields; + DHCP_IP_ADDRESS UNALIGNED *RouterAddress; + DHCP_IP_ADDRESS UNALIGNED *Server; + BYTE *ParameterRequestList; + DWORD ParameterRequestListLength; + CHAR *MachineName; + DWORD MachineNameLength; + BYTE ClientHardwareAddressType; + BYTE ClientHardwareAddressLength; + BYTE *ClientHardwareAddress; + CHAR *ClassIdentifier; + DWORD ClassIdentifierLength; + BYTE *VendorClass; + DWORD VendorClassLength; + DWORD DNSFlags; + DWORD DNSNameLength; + LPBYTE DNSName; + BOOLEAN DSDomainNameRequested; + CHAR *DSDomainName; + DWORD DSDomainNameLen; + DWORD UNALIGNED *ScopeId; +} DHCP_SERVER_OPTIONS, *LPDHCP_SERVER_OPTIONS; + +// +// The location in registry where the REG_MULTI_SZ list of callout DLLs +// that the DHCP Server will try to load. +// + +#define DHCP_CALLOUT_LIST_KEY L"System\\CurrentControlSet\\Services\\DHCPServer\\Parameters" +#define DHCP_CALLOUT_LIST_VALUE L"CalloutDlls" +#define DHCP_CALLOUT_LIST_TYPE REG_MULTI_SZ +#define DHCP_CALLOUT_ENTRY_POINT "DhcpServerCalloutEntry" + +// +// Control CODES used by DHCP Server to notify server state change. +// + +#define DHCP_CONTROL_START 0x00000001 +#define DHCP_CONTROL_STOP 0x00000002 +#define DHCP_CONTROL_PAUSE 0x00000003 +#define DHCP_CONTROL_CONTINUE 0x00000004 + +// +// Other ControlCodes used by various Callout HOOKS. +// + +#define DHCP_DROP_DUPLICATE 0x00000001 // duplicate of pkt being processed +#define DHCP_DROP_NOMEM 0x00000002 // not enough server mem in queues +#define DHCP_DROP_INTERNAL_ERROR 0x00000003 // ooops? +#define DHCP_DROP_TIMEOUT 0x00000004 // too late, pkt is too old +#define DHCP_DROP_UNAUTH 0x00000005 // server is not authorized to run +#define DHCP_DROP_PAUSED 0x00000006 // service is paused +#define DHCP_DROP_NO_SUBNETS 0x00000007 // no subnets configured on server +#define DHCP_DROP_INVALID 0x00000008 // invalid packet or client +#define DHCP_DROP_WRONG_SERVER 0x00000009 // client in different DS enterprise +#define DHCP_DROP_NOADDRESS 0x0000000A // no address available to offer +#define DHCP_DROP_PROCESSED 0x0000000B // packet has been processed +#define DHCP_DROP_GEN_FAILURE 0x00000100 // catch-all error +#define DHCP_SEND_PACKET 0x10000000 // send the packet on wire +#define DHCP_PROB_CONFLICT 0x20000001 // address conflicted.. +#define DHCP_PROB_DECLINE 0x20000002 // an addr got declined +#define DHCP_PROB_RELEASE 0x20000003 // an addr got released +#define DHCP_PROB_NACKED 0x20000004 // a client is being nacked. +#define DHCP_GIVE_ADDRESS_NEW 0x30000001 // give client a "new" address +#define DHCP_GIVE_ADDRESS_OLD 0x30000002 // renew client's "old" address +#define DHCP_CLIENT_BOOTP 0x30000003 // client is a BOOTP client +#define DHCP_CLIENT_DHCP 0x30000004 // client is a DHCP client + + + +typedef +DWORD +(APIENTRY *LPDHCP_CONTROL)( + IN DWORD dwControlCode, + IN LPVOID lpReserved +) +/*++ + +Routine Description: + + This routine is called whenever the DHCP Server service is + started, stopped, paused or continued as defined by the values of + the dwControlCode parameter. The lpReserved parameter is reserved + for future use and it should not be interpreted in any way. This + routine should not block. + +Arguments: + + dwControlCode - one of the DHCP_CONTROL_* values + lpReserved - reserved for future use. + +--*/ +; + +typedef +DWORD +(APIENTRY *LPDHCP_NEWPKT)( + IN OUT LPBYTE *Packet, + IN OUT DWORD *PacketSize, + IN DWORD IpAddress, + IN LPVOID Reserved, + IN OUT LPVOID *PktContext, + OUT LPBOOL ProcessIt +) +/*++ + +Routine Description: + + This routine is called soon after the DHCP Server receives a + packet that it attempts to process. This routine is in the + critical path of server execution and should return very fast, as + otherwise server performance will be impacted. The Callout DLL + can modify the buffer or return a new buffer via the Packet, + PacketSize arguments. Also, if the callout DLL has internal + structures to keep track of the packet and its progress, it can + then return a context to this packet in the PktContext parameter. + This context will be passed to almost all other hooks to indicate + the packet being referred to. Also, if the Callout DLL is + planning on processing the packet or for some other reason the + DHCP server is not expected to process this packet, then it can + set the ProcessIt flag to FALSE to indicate that the packet is to + be dropped. + +Arguments: + + Packet - This parameter points to a character buffer that holds + the actual packet received by the DHCP Server. + + PacketSize - This parameter points to a variable that holds the + size of the above buffer. + + IpAddress - This parameter points to an IPV4 host order IP address + of the socket that this packet was received on. + + Reserved -Reserved for future use. + + PktContect - This is an opaque pointer used by the DHCP Server for + future references to this packet. It is expected that the callout + DLL will provide this pointer if it is interested in keeping track + of the packet. (See the descriptions for the hooks below for + other usage of this Context). + + ProcessIt - This is a BOOL flag that the CalloutDll can set to + TRUE or reset to indicate if the DHCP Server should continue + processing this packet or not, respectively. + +--*/ +; + +typedef +DWORD +(APIENTRY *LPDHCP_DROP_SEND)( + IN OUT LPBYTE *Packet, + IN OUT DWORD *PacketSize, + IN DWORD ControlCode, + IN DWORD IpAddress, + IN LPVOID Reserved, + IN LPVOID PktContext +) +/*++ + +Routine Description: + + This hook is called if a packet is (DropPktHook) dropped for some + reason or if the packet is completely processed. (If a packet is + dropped, the hook is called twice as it is called once again to + note that the packet has been completely processed). The callout + DLL should be prepared to handle this hook multiple times for a + packet. This routine should not block. The ControlCode parameter + defines the reasons for the packet being dropped: + + * DHCP_DROP_DUPLICATE - This packet is a duplicate of another + received by the server. + * DHCP_DROP_NOMEM - Not enough memory to process the packet. + * DHCP_DROP_INTERNAL_ERROR - Unexpected nternal error occurred. + * DHCP_DROP_TIMEOUT - The packet is too old to process. + * DHCP_DROP_UNAUTH - The server is not authorized. + * DHCP_DROP_PAUSED - The server is paused. + * DHCP_DROP_NO_SUBNETS - There are no subnets configured. + * DHCP_DROP_INVALID - The packet is invalid or it came on an + invalid socket .. + * DHCP_DROP_WRONG_SERVER - The packet was sent to the wrong DHCP Server. + * DHCP_DROP_NOADDRESS - There is no address to offer. + * DHCP_DROP_PROCESSED - The packet has been processed. + * DHCP_DROP_GEN_FAILURE - An unknown error occurred. + + This routine is also called right before a response is sent down + the wire (SendPktHook) and in this case the ControlCode has a + value of DHCP_SEND_PACKET. + +Arguments: + + Packet - This parameter points to a character buffer that holds + the packet being processed by the DHCP Server. + + PacketSize - This parameter points to a variable that holds the + size of the above buffer. + + ControlCode - See description for various control codes. + + IpAddress - This parameter points to an IPV4 host order IP address + of the socket that this packet was received on. + + Reserved - Reserved for future use. + + PktContext - This parameter is the packet context that the Callout + DLL NewPkt Hook returned for this packet. This can be used to + track a packet. + +--*/ +; + +typedef +DWORD +(APIENTRY *LPDHCP_PROB)( + IN LPBYTE Packet, + IN DWORD PacketSize, + IN DWORD ControlCode, + IN DWORD IpAddress, + IN DWORD AltAddress, + IN LPVOID Reserved, + IN LPVOID PktContext +) +/*++ + +Routine Description: + + This routine is called whenever special events occur that cause + the packet to be dropped etc. The possible ControlCodes and their + meanings are as follows: + + * DHCP_PROB_CONFLICT - The address attempted to be offered + (AltAddress) is in use in the network already. + * DHCP_PROB_DECLINE - The packet was a DECLINE message for the + address specified in AltAddress. + * DHCP_PROB_RELEASE - The packet was a RELEASE message for the + address specified in AltAddress. + * DHCP_PROB_NACKED - The packet was a REQUEST message for address + specified in AltAddress and it was NACKed by the server. + + This routine should not block. + +Arguments: + + Packet - This parameter is the buffer of the packet being + processed. + + PacketSize - This is the size of the above buffer. + + ControlCode - Specifies the event. See description below for + control codes and meanings. + + IpAddress - IpV4 address of socket this packet was received on. + + AltAddress - Request IpV4 Address or Ip address that is in + conflict. + + Reserved - Reserve for future use. + + PktContext - This is the context returned by the NewPkt hook for + this packet. + +--*/ +; + +typedef +DWORD +(APIENTRY *LPDHCP_GIVE_ADDRESS)( + IN LPBYTE Packet, + IN DWORD PacketSize, + IN DWORD ControlCode, + IN DWORD IpAddress, + IN DWORD AltAddress, + IN DWORD AddrType, + IN DWORD LeaseTime, + IN LPVOID Reserved, + IN LPVOID PktContext +) +/*++ + +Routine Description: + + This routine is called when the server is about to send an ACK to + a REQUEST message. The ControlCode specifies if the address is a + totally new address or if it an renewal of an old address (with + values DHCP_GIVE_ADDRESS_NEW and DHCP_GIVE_ADDRESS_OLD + respectively). The address being offered is passed as the + AltAddress parameter and the AddrType parameter can be one of + DHCP_CLIENT_BOOTP or DHCP_CLIENT_DHCP indicating whether the + client is using BOOTP or DHCP respectively. This call should not + block. + +Arguments: + + Packet - This parameter is the buffer of the packet being + processed. + + PacketSize - This is the size of the above buffer. + + ControlCode - See description above for control codes and + meanings. + + IpAddress - IpV4 address of socket this packet was received on. + + AltAddress - IpV4 address being ACKed to the client. + + AddrType - Is this a DHCP or BOOTP address? + + LeaseTime - Lease duration being passed. + + Reserved - Reserve for future use. + + PktContext - This is the context returned by the NewPkt hook for + this packet. + +--*/ +; + +typedef +DWORD +(APIENTRY *LPDHCP_HANDLE_OPTIONS)( + IN LPBYTE Packet, + IN DWORD PacketSize, + IN LPVOID Reserved, + IN LPVOID PktContext, + IN OUT LPDHCP_SERVER_OPTIONS ServerOptions +) +/*++ + +Routine Description: + + This routine can be utilized by the CalloutDLL to avoid parsing + the whole packet. The packet is parsed by the server and some + commonly used options are returned in the parsed pointers + structure (see header for definition of DHCP_SERVER_OPTIONS). The + hook is expected to make a copy of the structure pointed to by + ServerOptions if it needs it beyond this function call. This + routine may be called several times for a single packet. This + routine should not block. + +Arguments: + + Packet - This parameter is the buffer of the packet being + processed. + + PacketSize - This is the size of the above buffer. + + Reserved - Reserve for future use. + + PktContext - This is the context returned by the NewPkt hook for + this packet. + + ServerOptions - This parameter is the structure that contains a + bunch of pointers that represent corresponding options. + +--*/ +; + +typedef +DWORD +(APIENTRY *LPDHCP_DELETE_CLIENT)( + IN DWORD IpAddress, + IN LPBYTE HwAddress, + IN ULONG HwAddressLength, + IN DWORD Reserved, + IN DWORD ClientType +) +/*++ + +Routine Description: + + This routine is called before a client lease is deleted off the + active leases database. The ClientType field is currently not + provided and this should not be used. This routine should not + block. + +Arguments: + + IpAddress - IpV4 address of the client lease being deleted. + + HwAddress - Buffer holding the Hardware address of the client (MAC). + + HwAddressLength - This specifies the length of the above buffer. + + Reserved - Reserved for future use. + + ClientType - Reserved for future use. +--*/ +; + +typedef +struct _DHCP_CALLOUT_TABLE { + LPDHCP_CONTROL DhcpControlHook; + LPDHCP_NEWPKT DhcpNewPktHook; + LPDHCP_DROP_SEND DhcpPktDropHook; + LPDHCP_DROP_SEND DhcpPktSendHook; + LPDHCP_PROB DhcpAddressDelHook; + LPDHCP_GIVE_ADDRESS DhcpAddressOfferHook; + LPDHCP_HANDLE_OPTIONS DhcpHandleOptionsHook; + LPDHCP_DELETE_CLIENT DhcpDeleteClientHook; + LPVOID DhcpExtensionHook; + LPVOID DhcpReservedHook; +} DHCP_CALLOUT_TABLE, *LPDHCP_CALLOUT_TABLE; + +typedef +DWORD +(APIENTRY *LPDHCP_ENTRY_POINT_FUNC) ( + IN LPWSTR ChainDlls, + IN DWORD CalloutVersion, + IN OUT LPDHCP_CALLOUT_TABLE CalloutTbl +) +/*++ + +Routine Description: + + This is the routine that is called by the DHCP Server when it + successfully loads a DLL. If the routine succeeds, then the + DHCP Server does not attempt to load any of the DLLs specified in + the ChainDlls list of DLLs. If this function fails for some + reason, then the DHCP Server proceeds to the next DLL in the + ChainDlls structure. + + Note that for version negotiation, the server may call this + routine several times until a compatible version is found. + + It is expected that the entrypoint routine would walk through the + names of the dlls and attempt to load each of them and when it + succeeds in retrieving the entry point, it attempts to get the + cumulative set of hooks by repeating the above procedure (as done + by the DHCP Server). + +Arguments: + + ChainDlls - This is a set of DLL names in REG_MULTI_SZ format (as + returned by Registry function calls). This does not contain the + name of the current DLL itself, but only the names of all DLLs + that follow the current DLL. + + CalloutVersion - This is the version that the Callout DLL is + expected to support. The current version number is 0. + + CalloutTbl - This is the cumulative set of Hooks that is needed by + the current DLLs as well as all the DLLs in ChainDlls. It is the + responsibility of the current DLL to retrive the cumulative set of + Hooks and merge that with its own set of hooks and return that in + this table structure. The table structure is defined above. + +--*/ +; + +#ifdef __cplusplus +} +#endif + +#endif _CALLOUT_H_ + +//======================================================================== +// end of file +//======================================================================== + diff --git a/utils/fci.h b/utils/fci.h new file mode 100644 index 0000000..632180b --- /dev/null +++ b/utils/fci.h @@ -0,0 +1,648 @@ +/*** types.h - Common defines for FCI/FDI stuff -- goes into FCI/FDI.H + * + * Copyright (C) Microsoft Corporation + * All Rights Reserved. + * + */ + +#ifndef INCLUDED_TYPES_FCI_FDI +#define INCLUDED_TYPES_FCI_FDI 1 + +#ifdef __cplusplus +extern "C" { /* Assume C declarations for C++ */ +#endif /* __cplusplus */ + + +//** Define away for 32-bit build +#ifndef HUGE +#define HUGE +#endif + +#ifndef FAR +#define FAR +#endif + + +#ifndef DIAMONDAPI +#define DIAMONDAPI __cdecl +#endif + + +//** Specify structure packing explicitly for clients of FDI + +#ifndef _WIN64 +#include +#endif + + +//** Don't redefine types defined in Win16 WINDOWS.H (_INC_WINDOWS) +// or Win32 WINDOWS.H (_WINDOWS_) +// +#if !defined(_INC_WINDOWS) && !defined(_WINDOWS_) +typedef int BOOL; /* f */ +typedef unsigned char BYTE; /* b */ +typedef unsigned int UINT; /* ui */ +typedef unsigned short USHORT; /* us */ +typedef unsigned long ULONG; /* ul */ +#endif // _INC_WINDOWS + +typedef unsigned long CHECKSUM; /* csum */ + +typedef unsigned long UOFF; /* uoff - uncompressed offset */ +typedef unsigned long COFF; /* coff - cabinet file offset */ + + +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef NULL +#define NULL 0 +#endif + + +/*** ERF - Error structure + * + * This structure returns error information from FCI/FDI. The caller should + * not modify this structure. + */ +typedef struct { + int erfOper; // FCI/FDI error code -- see FDIERROR_XXX + // and FCIERR_XXX equates for details. + + int erfType; // Optional error value filled in by FCI/FDI. + // For FCI, this is usually the C run-time + // *errno* value. + + BOOL fError; // TRUE => error present +} ERF; /* erf */ +typedef ERF FAR *PERF; /* perf */ + +#ifdef _DEBUG +// don't hide statics from map during debugging +#define STATIC +#else // !DEBUG +#define STATIC static +#endif // !DEBUG + +#define CB_MAX_CHUNK 32768U +#define CB_MAX_DISK 0x7fffffffL +#define CB_MAX_FILENAME 256 +#define CB_MAX_CABINET_NAME 256 +#define CB_MAX_CAB_PATH 256 +#define CB_MAX_DISK_NAME 256 + +/*** tcompXXX - Diamond compression types + * + * These are passed to FCIAddFile(), and are also stored in the CFFOLDER + * structures in cabinet files. + * + * NOTE: We reserve bits for the TYPE, QUANTUM_LEVEL, and QUANTUM_MEM + * to provide room for future expansion. Since this value is stored + * in the CFDATA records in the cabinet file, we don't want to + * have to change the format for existing compression configurations + * if we add new ones in the future. This will allows us to read + * old cabinet files in the future. + */ + +typedef unsigned short TCOMP; /* tcomp */ + +#define tcompMASK_TYPE 0x000F // Mask for compression type +#define tcompTYPE_NONE 0x0000 // No compression +#define tcompTYPE_MSZIP 0x0001 // MSZIP +#define tcompTYPE_QUANTUM 0x0002 // Quantum +#define tcompTYPE_LZX 0x0003 // LZX +#define tcompBAD 0x000F // Unspecified compression type + +#define tcompMASK_LZX_WINDOW 0x1F00 // Mask for LZX Compression Memory +#define tcompLZX_WINDOW_LO 0x0F00 // Lowest LZX Memory (15) +#define tcompLZX_WINDOW_HI 0x1500 // Highest LZX Memory (21) +#define tcompSHIFT_LZX_WINDOW 8 // Amount to shift over to get int + +#define tcompMASK_QUANTUM_LEVEL 0x00F0 // Mask for Quantum Compression Level +#define tcompQUANTUM_LEVEL_LO 0x0010 // Lowest Quantum Level (1) +#define tcompQUANTUM_LEVEL_HI 0x0070 // Highest Quantum Level (7) +#define tcompSHIFT_QUANTUM_LEVEL 4 // Amount to shift over to get int + +#define tcompMASK_QUANTUM_MEM 0x1F00 // Mask for Quantum Compression Memory +#define tcompQUANTUM_MEM_LO 0x0A00 // Lowest Quantum Memory (10) +#define tcompQUANTUM_MEM_HI 0x1500 // Highest Quantum Memory (21) +#define tcompSHIFT_QUANTUM_MEM 8 // Amount to shift over to get int + +#define tcompMASK_RESERVED 0xE000 // Reserved bits (high 3 bits) + + + +#define CompressionTypeFromTCOMP(tc) \ + ((tc) & tcompMASK_TYPE) + +#define CompressionLevelFromTCOMP(tc) \ + (((tc) & tcompMASK_QUANTUM_LEVEL) >> tcompSHIFT_QUANTUM_LEVEL) + +#define CompressionMemoryFromTCOMP(tc) \ + (((tc) & tcompMASK_QUANTUM_MEM) >> tcompSHIFT_QUANTUM_MEM) + +#define TCOMPfromTypeLevelMemory(t,l,m) \ + (((m) << tcompSHIFT_QUANTUM_MEM ) | \ + ((l) << tcompSHIFT_QUANTUM_LEVEL) | \ + ( t )) + +#define LZXCompressionWindowFromTCOMP(tc) \ + (((tc) & tcompMASK_LZX_WINDOW) >> tcompSHIFT_LZX_WINDOW) + +#define TCOMPfromLZXWindow(w) \ + (((w) << tcompSHIFT_LZX_WINDOW ) | \ + ( tcompTYPE_LZX )) + + +//** Revert to default structure packing + +#ifndef _WIN64 +#include +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // !INCLUDED_TYPES_FCI_FDI +/*** fci_int.h - File Compression Interface definitions + * + * Copyright (C) Microsoft Corporation 1993-1994 + * All Rights Reserved. + * + * Author: + * Chuck Strouss + * + * History: + * 09-Jan-1994 chuckst Contents moved to bfol.h, this file is a + * placeholder for the new 'higher-level' fci + * 14-Feb-1994 bens Cleaned up some comments. + * 09-Mar-1994 bens Added error codes (moved from buildcab.h); + * Added RESERVE control + * 17-Mar-1994 bens Specify structure packing explicitly + * 21-Mar-1994 bens Cleaned up names + * 22-Mar-1994 bens Documented error cods + * 29-Mar-1994 bens Add FCIFlushFolder, renamed FCIFlushCabinet + * 18-Apr-1994 bens Changed CDECL to DIAMONDAPI + * 18-May-1994 bens Add ccab.fFailOnIncompressible field for + * Chicago M6 hack. + * 11-Nov-2005 kinshu SAL annotation + */ + +#ifndef INCLUDED_FCI +#define INCLUDED_FCI 1 + +#include +typedef __nullterminated char* LPSTR; +#include + +#ifdef __cplusplus +extern "C" { /* Assume C declarations for C++ */ +#endif /* __cplusplus */ + +//** Specify structure packing explicitly for clients of FCI + +#ifndef _WIN64 +#include +#endif + + +/*** FCIERROR - Error codes returned in erf.erfOper field + * + */ +typedef enum { +FCIERR_NONE, // No error + +FCIERR_OPEN_SRC, // Failure opening file to be stored in cabinet + // erf.erfTyp has C run-time *errno* value + +FCIERR_READ_SRC, // Failure reading file to be stored in cabinet + // erf.erfTyp has C run-time *errno* value + +FCIERR_ALLOC_FAIL, // Out of memory in FCI + +FCIERR_TEMP_FILE, // Could not create a temporary file + // erf.erfTyp has C run-time *errno* value + +FCIERR_BAD_COMPR_TYPE, // Unknown compression type + +FCIERR_CAB_FILE, // Could not create cabinet file + // erf.erfTyp has C run-time *errno* value + +FCIERR_USER_ABORT, // Client requested abort + +FCIERR_MCI_FAIL, // Failure compressing data + +FCIERR_CAB_FORMAT_LIMIT // Data-size or file-count exceeded CAB format limits + // i.e. Total-bytes (uncompressed) in a CAB-folder exceeded 0x7FFF8000 (~ 2GB) + // or, CAB size (compressed) exceeded 0x7FFFFFFF + // or, File-count in CAB exceeded 0xFFFF + +} FCIERROR; + + +/* + * FAT file attribute flag used by FCI/FDI to indicate that + * the filename in the CAB is a UTF string + */ +#ifndef _A_NAME_IS_UTF +#define _A_NAME_IS_UTF 0x80 +#endif + +/* + * FAT file attribute flag used by FCI/FDI to indicate that + * the file should be executed after extraction + */ +#ifndef _A_EXEC +#define _A_EXEC 0x40 +#endif + + +/*** HFCI - Handle to an FCI Context + * + */ +typedef void * HFCI; + + +/*** CCAB - Current Cabinet + * + * This structure is used for passing in the cabinet parameters to FCI, + * and is passed back on certain FCI callbacks to provide cabinet + * information to the client. + */ +typedef struct { +// longs first + ULONG cb; // size available for cabinet on this media + ULONG cbFolderThresh; // Thresshold for forcing a new Folder + +// then ints + UINT cbReserveCFHeader; // Space to reserve in CFHEADER + UINT cbReserveCFFolder; // Space to reserve in CFFOLDER + UINT cbReserveCFData; // Space to reserve in CFDATA + int iCab; // sequential numbers for cabinets + int iDisk; // Disk number +#ifndef REMOVE_CHICAGO_M6_HACK + int fFailOnIncompressible; // TRUE => Fail if a block is incompressible +#endif + +// then shorts + USHORT setID; // Cabinet set ID + +// then chars + char szDisk[CB_MAX_DISK_NAME]; // current disk name + char szCab[CB_MAX_CABINET_NAME]; // current cabinet name + char szCabPath[CB_MAX_CAB_PATH]; // path for creating cabinet +} CCAB; /* ccab */ +typedef CCAB *PCCAB; /* pccab */ + + +/*** FNALLOC - Memory Allocation + * FNFREE - Memory Free + * + * These are modeled after the C run-time routines malloc() and free() + * (16-bit clients please note -- the size is a ULONG, so you may need + * to write a wrapper routine for halloc!). FDI expects error + * handling to be identical to these C run-time routines. + * + * As long as you faithfully copy the semantics of malloc() and free(), + * you can supply any functions you like! + * + * WARNING: You should never assume anything about the sequence of + * PFNALLOC and PFNFREE calls -- incremental releases of + * Diamond/FDI may have radically different numbers of + * PFNALLOC calls and allocation sizes! + */ +//** Memory functions for FCI +typedef void HUGE * (FAR DIAMONDAPI *PFNFCIALLOC)(ULONG cb); /* pfna */ +#define FNFCIALLOC(fn) void HUGE * FAR DIAMONDAPI fn(ULONG cb) + +typedef void (FAR DIAMONDAPI *PFNFCIFREE)(void HUGE *memory); /* pfnf */ +#define FNFCIFREE(fn) void FAR DIAMONDAPI fn(void HUGE *memory) + + +//** File I/O functions for FCI +typedef INT_PTR (FAR DIAMONDAPI *PFNFCIOPEN) (__in LPSTR pszFile, int oflag, int pmode, int FAR *err, void FAR *pv); +typedef UINT (FAR DIAMONDAPI *PFNFCIREAD) (INT_PTR hf, void FAR *memory, UINT cb, int FAR *err, void FAR *pv); +typedef UINT (FAR DIAMONDAPI *PFNFCIWRITE)(INT_PTR hf, void FAR *memory, UINT cb, int FAR *err, void FAR *pv); +typedef int (FAR DIAMONDAPI *PFNFCICLOSE)(INT_PTR hf, int FAR *err, void FAR *pv); +typedef long (FAR DIAMONDAPI *PFNFCISEEK) (INT_PTR hf, long dist, int seektype, int FAR *err, void FAR *pv); +typedef int (FAR DIAMONDAPI *PFNFCIDELETE) (__in LPSTR pszFile, int FAR *err, void FAR *pv); + +#define FNFCIOPEN(fn) INT_PTR FAR DIAMONDAPI fn(__in LPSTR pszFile, int oflag, int pmode, int FAR *err, void FAR *pv) +#define FNFCIREAD(fn) UINT FAR DIAMONDAPI fn(INT_PTR hf, void FAR *memory, UINT cb, int FAR *err, void FAR *pv) +#define FNFCIWRITE(fn) UINT FAR DIAMONDAPI fn(INT_PTR hf, void FAR *memory, UINT cb, int FAR *err, void FAR *pv) +#define FNFCICLOSE(fn) int FAR DIAMONDAPI fn(INT_PTR hf, int FAR *err, void FAR *pv) +#define FNFCISEEK(fn) long FAR DIAMONDAPI fn(INT_PTR hf, long dist, int seektype, int FAR *err, void FAR *pv) +#define FNFCIDELETE(fn) int FAR DIAMONDAPI fn(__in LPSTR pszFile, int FAR *err, void FAR *pv) + + +/*** FNFCIGETNEXTCABINET - Callback used to request new cabinet info + * + * Entry: + * pccab - Points to copy of old ccab structure to modify + * cbPrevCab - Estimate of size of previous cabinet + * pv - Has the caller's context pointer + * + * Exit-Success: + * returns TRUE; + * + * Exit-Failure: + * returns FALSE; + */ +typedef BOOL (DIAMONDAPI *PFNFCIGETNEXTCABINET)(PCCAB pccab, + ULONG cbPrevCab, + void FAR *pv); /* pfnfcignc */ + +#define FNFCIGETNEXTCABINET(fn) BOOL DIAMONDAPI fn(PCCAB pccab, \ + ULONG cbPrevCab, \ + void FAR *pv) + + +/*** FNFCIFILEPLACED - Notify FCI client that file was placed + * + * Entry: + * pccab - cabinet structure to fill in, with copy of previous one + * pszFile - name of file, from cabinet + * cbFile - length of file + * fContinuation - true if this is a later segment of a continued file + * pv - the context of the client + * + * Exit-Success: + * return value anything but -1 + * + * Exit-Failure: + * return value -1 means to abort + */ +typedef int (DIAMONDAPI *PFNFCIFILEPLACED)(PCCAB pccab, + __in LPSTR pszFile, + long cbFile, + BOOL fContinuation, + void FAR *pv); /* pfnfcifp */ + +#define FNFCIFILEPLACED(fn) int DIAMONDAPI fn(PCCAB pccab, \ + __in LPSTR pszFile, \ + long cbFile, \ + BOOL fContinuation, \ + void FAR *pv) + + +/*** FNCDIGETOPENINFO - Open source file, get date/time/attribs + * + * Entry: + * pszName -- complete path to filename + * pdate -- location to return FAT-style date code + * ptime -- location to return FAT-style time code + * pattribs -- location to return FAT-style attributes + * pv -- client's context + * + * Exit-Success: + * Return value is file handle of open file to read + * + * Exit-Failure: + * Return value is -1 + */ +typedef INT_PTR (DIAMONDAPI *PFNFCIGETOPENINFO)(__in LPSTR pszName, + USHORT *pdate, + USHORT *ptime, + USHORT *pattribs, + int FAR *err, + void FAR *pv); /* pfnfcigoi */ + +#define FNFCIGETOPENINFO(fn) INT_PTR DIAMONDAPI fn(__in LPSTR pszName, \ + USHORT *pdate, \ + USHORT *ptime, \ + USHORT *pattribs, \ + int FAR *err, \ + void FAR *pv) + +/*** FNFCISTATUS - Status/Cabinet Size callback + * + * Entry: + * typeStatus == statusFile if compressing a block into a folder + * cb1 = Size of compressed block + * cb2 = Size of uncompressed block + * + * typeStatus == statusFolder if adding a folder to a cabinet + * cb1 = Amount of folder copied to cabinet so far + * cb2 = Total size of folder + * + * typeStatus == statusCabinet if writing out a complete cabinet + * cb1 = Estimated cabinet size that was previously + * passed to fnfciGetNextCabinet(). + * cb2 = Actual cabinet size + * NOTE: Return value is desired client size for cabinet + * file. FCI updates the maximum cabinet size + * remaining using this value. This allows a client + * to generate multiple cabinets per disk, and have + * FCI limit the size correctly -- the client can do + * cluster size rounding on the cabinet size! + * The client should either return cb2, or round cb2 + * up to some larger value and return that. + * Exit-Success: + * Returns anything other than -1; + * NOTE: See statusCabinet for special return values! + * + * Exit-Failure: + * Returns -1 to signal that FCI should abort; + */ + +#define statusFile 0 // Add File to Folder callback +#define statusFolder 1 // Add Folder to Cabinet callback +#define statusCabinet 2 // Write out a completed cabinet callback + +typedef long (DIAMONDAPI *PFNFCISTATUS)(UINT typeStatus, + ULONG cb1, + ULONG cb2, + void FAR *pv); /* pfnfcis */ + +#define FNFCISTATUS(fn) long DIAMONDAPI fn(UINT typeStatus, \ + ULONG cb1, \ + ULONG cb2, \ + void FAR *pv) + + +/*** FNFCIGETTEMPFILE - Callback, requests temporary file name + * + * Entry: + * pszTempName - Buffer to receive complete tempfile name + * cbTempName - Size of pszTempName buffer + * + * Exit-Success: + * return TRUE + * + * Exit-Failure: + * return FALSE; could not create tempfile, or buffer too small + * + * Note: + * It is conceivable that this function may return a filename + * that will already exist by the time it is opened. For this + * reason, the caller should make several attempts to create + * temporary files before giving up. + */ +typedef BOOL (DIAMONDAPI *PFNFCIGETTEMPFILE)(__out_bcount(cbTempName) char *pszTempName, + __in_range(>=, MAX_PATH) int cbTempName, + void FAR *pv); /* pfnfcigtf */ + +#define FNFCIGETTEMPFILE(fn) BOOL DIAMONDAPI fn(__out_bcount(cbTempName) char *pszTempName, \ + __in_range(>=, MAX_PATH) int cbTempName, \ + void FAR *pv) + + +/*** FCICreate -- create an FCI context (an open CAB, an open FOL) + * + * Entry: + * perf - structure where we return error codes + * pfnfcifp - callback to inform caller of eventual dest of files + * pfna - memory allocation function callback + * pfnf - memory free function callback + * pfnfcigtf - temp file name generator callback + * pccab - pointer to cabinet/disk name & size structure + * + * Notes: + * (1) The alloc/free callbacks must remain valid throughout + * the life of the context, up to and including the call to + * FCIDestroy. + * (2) The perf pointer is stored in the compression context (HCI), + * and any errors from subsequent FCI calls are stored in the + * erf that was passed in on *this* call. + * + * Exit-Success: + * Returns non-NULL handle to an FCI context. + * + * Exit-Failure: + * Returns NULL, perf filled in. + */ +HFCI DIAMONDAPI FCICreate(__in PERF perf, + __callback PFNFCIFILEPLACED pfnfcifp, + __callback PFNFCIALLOC pfna, + __callback PFNFCIFREE pfnf, + __callback PFNFCIOPEN pfnopen, + __callback PFNFCIREAD pfnread, + __callback PFNFCIWRITE pfnwrite, + __callback PFNFCICLOSE pfnclose, + __callback PFNFCISEEK pfnseek, + __callback PFNFCIDELETE pfndelete, + __callback PFNFCIGETTEMPFILE pfnfcigtf, + __in PCCAB pccab, + __in_opt void FAR *pv + ); + + +/*** FCIAddFile - Add a disk file to a folder/cabinet + * + * Entry: + * hfci - FCI context handle + * pszSourceFile - Name of file to add to folder + * pszFileName - Name to store into folder/cabinet + * fExecute - Flag indicating execute on extract + * pfn_progress - Progress callback + * pfnfcignc - GetNextCabinet callback + * pfnfcis - Status callback + * pfnfcigoi - OpenInfo callback + * typeCompress - Type of compression to use for this file + * pv - pointer to caller's internal context + * + * Exit-Success: + * returns TRUE + * + * Exit-Failure: + * returns FALSE, error filled in + * + * This is the main function used to add file(s) to a cabinet + * or series of cabinets. If the current file causes the current + * folder/cabinet to overflow the disk image currently being built, + * the cabinet will be terminated, and a new cabinet/disk name will + * be prompted for via a callback. The pending folder will be trimmed + * of the data which has already been generated in the finished cabinet. + */ +BOOL DIAMONDAPI FCIAddFile(__in HFCI hfci, + __in LPSTR pszSourceFile, + __in LPSTR pszFileName, + BOOL fExecute, + __callback PFNFCIGETNEXTCABINET pfnfcignc, + __callback PFNFCISTATUS pfnfcis, + __callback PFNFCIGETOPENINFO pfnfcigoi, + TCOMP typeCompress + ); + + +/*** FCIFlushCabinet - Complete the current cabinet under construction + * + * This will cause the current cabinet (assuming it is not empty) to + * be gathered together and written to disk. + * + * Entry: + * hfci - FCI context + * fGetNextCab - TRUE => Call GetNextCab to get continuation info; + * FALSE => Don't call GetNextCab unless this cabinet + * overflows. + * pfnfcignc - callback function to get continuation cabinets + * pfnfcis - callback function for progress reporting + * pv - caller's internal context for callbacks + * + * Exit-Success: + * return code TRUE + * + * Exit-Failure: + * return code FALSE, error structure filled in + */ +BOOL DIAMONDAPI FCIFlushCabinet(__in HFCI hfci, + BOOL fGetNextCab, + __callback PFNFCIGETNEXTCABINET pfnfcignc, + __callback PFNFCISTATUS pfnfcis + ); + + +/*** FCIFlushFolder - Complete the current folder under construction + * + * This will force the termination of the current folder, which may or + * may not cause one or more cabinet files to be completed. + * + * Entry: + * hfci - FCI context + * GetNextCab - callback function to get continuation cabinets + * pfnProgress - callback function for progress reporting + * pv - caller's internal context for callbacks + * + * Exit-Success: + * return code TRUE + * + * Exit-Failure: + * return code FALSE, error structure filled in + */ +BOOL DIAMONDAPI FCIFlushFolder(__in HFCI hfci, + __callback PFNFCIGETNEXTCABINET pfnfcignc, + __callback PFNFCISTATUS pfnfcis + ); + + +/*** FCIDestroy - Destroy a FCI context and delete temp files + * + * Entry: + * hfci - FCI context + * + * Exit-Success: + * return code TRUE + * + * Exit-Failure: + * return code FALSE, error structure filled in + */ +BOOL DIAMONDAPI FCIDestroy (__in HFCI hfci); + +//** Revert to default structure packing + +#ifndef _WIN64 +#include +#endif + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif // !INCLUDED_FCI + diff --git a/utils/midles.h b/utils/midles.h new file mode 100644 index 0000000..eede126 --- /dev/null +++ b/utils/midles.h @@ -0,0 +1,296 @@ +/*++ + +Copyright (c) Microsoft Corporation. All rights reserved. + +Module Name: + + midles.h + +Abstract: + + This module contains definitions needed for encoding/decoding + support (serializing/deserializing a.k.a. pickling). + +--*/ + +#ifndef __MIDLES_H__ +#define __MIDLES_H__ + +#if _MSC_VER > 1000 +#pragma once +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Pickling support + */ +typedef enum +{ + MES_ENCODE, + MES_DECODE, + MES_ENCODE_NDR64 +} MIDL_ES_CODE; + +typedef enum +{ + MES_INCREMENTAL_HANDLE, + MES_FIXED_BUFFER_HANDLE, + MES_DYNAMIC_BUFFER_HANDLE +} MIDL_ES_HANDLE_STYLE; + + +typedef void (__RPC_USER * MIDL_ES_ALLOC ) + ( IN OUT void * state, + OUT char ** pbuffer, + IN OUT unsigned int * psize ); + +typedef void (__RPC_USER * MIDL_ES_WRITE) + ( IN OUT void * state, + IN char * buffer, + IN unsigned int size ); + +typedef void (__RPC_USER * MIDL_ES_READ) + ( IN OUT void * state, + OUT char ** pbuffer, + IN OUT unsigned int * psize ); + +typedef handle_t MIDL_ES_HANDLE; + +typedef struct _MIDL_TYPE_PICKLING_INFO +{ + unsigned long Version; + unsigned long Flags; + UINT_PTR Reserved[3]; +} MIDL_TYPE_PICKLING_INFO, * PMIDL_TYPE_PICKLING_INFO; + + +RPC_STATUS RPC_ENTRY +MesEncodeIncrementalHandleCreate( + void * UserState, + MIDL_ES_ALLOC AllocFn, + MIDL_ES_WRITE WriteFn, + handle_t * pHandle ); + +RPC_STATUS RPC_ENTRY +MesDecodeIncrementalHandleCreate( + void * UserState, + MIDL_ES_READ ReadFn, + handle_t * pHandle ); + + +RPC_STATUS RPC_ENTRY +MesIncrementalHandleReset( + handle_t Handle, + void * UserState, + MIDL_ES_ALLOC AllocFn, + MIDL_ES_WRITE WriteFn, + MIDL_ES_READ ReadFn, + MIDL_ES_CODE Operation ); + + +RPC_STATUS RPC_ENTRY +MesEncodeFixedBufferHandleCreate( + __out_bcount(BufferSize) char *pBuffer, + __in unsigned long BufferSize, + __out unsigned long *pEncodedSize, + __out handle_t *pHandle + ); + +RPC_STATUS RPC_ENTRY +MesEncodeDynBufferHandleCreate( + __deref_out_bcount(*pEncodedSize) char **pBuffer, + __out unsigned long *pEncodedSize, + __out handle_t *pHandle + ); + +RPC_STATUS RPC_ENTRY +MesDecodeBufferHandleCreate( + __bcount(BufferSize) char *pBuffer, + __out unsigned long BufferSize, + __out handle_t *pHandle + ); + + +RPC_STATUS RPC_ENTRY +MesBufferHandleReset( + __in handle_t Handle, + __in unsigned long HandleStyle, + __in MIDL_ES_CODE Operation, + __deref_in_bcount_opt(BufferSize) char **pBuffer, + __in unsigned long BufferSize, + __out unsigned long *pEncodedSize + ); + + +RPC_STATUS RPC_ENTRY +MesHandleFree( handle_t Handle ); + +RPC_STATUS RPC_ENTRY +MesInqProcEncodingId( + handle_t Handle, + PRPC_SYNTAX_IDENTIFIER pInterfaceId, + unsigned long * pProcNum ); + + +size_t RPC_ENTRY +NdrMesSimpleTypeAlignSize ( handle_t ); + +void RPC_ENTRY +NdrMesSimpleTypeDecode( + handle_t Handle, + void * pObject, + short Size ); + +void RPC_ENTRY +NdrMesSimpleTypeEncode( + handle_t Handle, + const MIDL_STUB_DESC * pStubDesc, + const void * pObject, + short Size ); + + +size_t RPC_ENTRY +NdrMesTypeAlignSize( + handle_t Handle, + const MIDL_STUB_DESC * pStubDesc, + PFORMAT_STRING pFormatString, + const void * pObject ); + +void RPC_ENTRY +NdrMesTypeEncode( + handle_t Handle, + const MIDL_STUB_DESC * pStubDesc, + PFORMAT_STRING pFormatString, + const void * pObject ); + +void RPC_ENTRY +NdrMesTypeDecode( + handle_t Handle, + const MIDL_STUB_DESC * pStubDesc, + PFORMAT_STRING pFormatString, + void * pObject ); + +size_t RPC_ENTRY +NdrMesTypeAlignSize2( + handle_t Handle, + const MIDL_TYPE_PICKLING_INFO * pPicklingInfo, + const MIDL_STUB_DESC * pStubDesc, + PFORMAT_STRING pFormatString, + const void * pObject ); + +void RPC_ENTRY +NdrMesTypeEncode2( + handle_t Handle, + const MIDL_TYPE_PICKLING_INFO * pPicklingInfo, + const MIDL_STUB_DESC * pStubDesc, + PFORMAT_STRING pFormatString, + const void * pObject ); + +void RPC_ENTRY +NdrMesTypeDecode2( + handle_t Handle, + const MIDL_TYPE_PICKLING_INFO * pPicklingInfo, + const MIDL_STUB_DESC * pStubDesc, + PFORMAT_STRING pFormatString, + void * pObject ); + +void RPC_ENTRY +NdrMesTypeFree2( + handle_t Handle, + const MIDL_TYPE_PICKLING_INFO * pPicklingInfo, + const MIDL_STUB_DESC * pStubDesc, + PFORMAT_STRING pFormatString, + void * pObject ); + +void RPC_VAR_ENTRY +NdrMesProcEncodeDecode( + handle_t Handle, + const MIDL_STUB_DESC * pStubDesc, + PFORMAT_STRING pFormatString, + ... ); + +CLIENT_CALL_RETURN RPC_VAR_ENTRY +NdrMesProcEncodeDecode2( + handle_t Handle, + const MIDL_STUB_DESC * pStubDesc, + PFORMAT_STRING pFormatString, + ... + ); + + +// ndr64 entries. +size_t RPC_ENTRY +NdrMesTypeAlignSize3( + handle_t Handle, + const MIDL_TYPE_PICKLING_INFO * pPicklingInfo, + const MIDL_STUBLESS_PROXY_INFO* pProxyInfo, + const unsigned long * ArrTypeOffset[], + unsigned long nTypeIndex, + const void * pObject ); + +void RPC_ENTRY +NdrMesTypeEncode3( + handle_t Handle, + const MIDL_TYPE_PICKLING_INFO * pPicklingInfo, + const MIDL_STUBLESS_PROXY_INFO* pProxyInfo, + const unsigned long * ArrTypeOffset[], + unsigned long nTypeIndex, + const void * pObject ); + +void RPC_ENTRY +NdrMesTypeDecode3( + handle_t Handle, + const MIDL_TYPE_PICKLING_INFO * pPicklingInfo, + const MIDL_STUBLESS_PROXY_INFO* pProxyInfo, + const unsigned long * ArrTypeOffset[], + unsigned long nTypeIndex, + void * pObject ); + +void RPC_ENTRY +NdrMesTypeFree3( + handle_t Handle, + const MIDL_TYPE_PICKLING_INFO * pPicklingInfo, + const MIDL_STUBLESS_PROXY_INFO* pProxyInfo, + const unsigned long * ArrTypeOffset[], + unsigned long nTypeIndex, + void * pObject ); + + +CLIENT_CALL_RETURN RPC_VAR_ENTRY +NdrMesProcEncodeDecode3( + handle_t Handle, + const MIDL_STUBLESS_PROXY_INFO* pProxyInfo, + unsigned long nProcNum, + void *pReturnValue, + ... ); + +void RPC_ENTRY +NdrMesSimpleTypeDecodeAll( + handle_t Handle, + const MIDL_STUBLESS_PROXY_INFO* pProxyInfo, + void * pObject, + short Size ); + +void RPC_ENTRY +NdrMesSimpleTypeEncodeAll( + handle_t Handle, + const MIDL_STUBLESS_PROXY_INFO* pProxyInfo, + const void * pObject, + short Size ); + +size_t RPC_ENTRY +NdrMesSimpleTypeAlignSizeAll ( handle_t Handle, + const MIDL_STUBLESS_PROXY_INFO* pProxyInfo ); + + +#ifdef __cplusplus +} +#endif + +#endif /* __MIDLES_H__ */ +