--- /dev/null
- if (dwSecurityInformation & (DACL_SECURITY_INFORMATION ||
- GROUP_SECURITY_INFORMATION ||
+/*
+ * PROJECT: ReactOS Service Control Manager
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: base/system/services/rpcserver.c
+ * PURPOSE: RPC server interface for the advapi32 calls
+ * COPYRIGHT: Copyright 2005-2006 Eric Kohl
+ * Copyright 2006-2007 Hervé Poussineau <hpoussin@reactos.org>
+ * Copyright 2007 Ged Murphy <gedmurphy@reactos.org>
+ */
+
+/* INCLUDES ****************************************************************/
+
+#include "services.h"
+#include "svcctl_s.h"
+
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS *****************************************************************/
+
+#define MANAGER_TAG 0x72674D68 /* 'hMgr' */
+#define SERVICE_TAG 0x63765368 /* 'hSvc' */
+
+typedef struct _SCMGR_HANDLE
+{
+ DWORD Tag;
+ DWORD DesiredAccess;
+} SCMGR_HANDLE;
+
+
+typedef struct _MANAGER_HANDLE
+{
+ SCMGR_HANDLE Handle;
+ WCHAR DatabaseName[1];
+} MANAGER_HANDLE, *PMANAGER_HANDLE;
+
+
+typedef struct _SERVICE_HANDLE
+{
+ SCMGR_HANDLE Handle;
+ PSERVICE ServiceEntry;
+} SERVICE_HANDLE, *PSERVICE_HANDLE;
+
+
+#define SC_MANAGER_READ \
+ (STANDARD_RIGHTS_READ | \
+ SC_MANAGER_QUERY_LOCK_STATUS | \
+ SC_MANAGER_ENUMERATE_SERVICE)
+
+#define SC_MANAGER_WRITE \
+ (STANDARD_RIGHTS_WRITE | \
+ SC_MANAGER_MODIFY_BOOT_CONFIG | \
+ SC_MANAGER_CREATE_SERVICE)
+
+#define SC_MANAGER_EXECUTE \
+ (STANDARD_RIGHTS_EXECUTE | \
+ SC_MANAGER_LOCK | \
+ SC_MANAGER_ENUMERATE_SERVICE | \
+ SC_MANAGER_CONNECT | \
+ SC_MANAGER_CREATE_SERVICE)
+
+
+#define SERVICE_READ \
+ (STANDARD_RIGHTS_READ | \
+ SERVICE_INTERROGATE | \
+ SERVICE_ENUMERATE_DEPENDENTS | \
+ SERVICE_QUERY_STATUS | \
+ SERVICE_QUERY_CONFIG)
+
+#define SERVICE_WRITE \
+ (STANDARD_RIGHTS_WRITE | \
+ SERVICE_CHANGE_CONFIG)
+
+#define SERVICE_EXECUTE \
+ (STANDARD_RIGHTS_EXECUTE | \
+ SERVICE_USER_DEFINED_CONTROL | \
+ SERVICE_PAUSE_CONTINUE | \
+ SERVICE_STOP | \
+ SERVICE_START)
+
+
+/* VARIABLES ***************************************************************/
+
+static GENERIC_MAPPING
+ScmManagerMapping = {SC_MANAGER_READ,
+ SC_MANAGER_WRITE,
+ SC_MANAGER_EXECUTE,
+ SC_MANAGER_ALL_ACCESS};
+
+static GENERIC_MAPPING
+ScmServiceMapping = {SERVICE_READ,
+ SERVICE_WRITE,
+ SERVICE_EXECUTE,
+ SC_MANAGER_ALL_ACCESS};
+
+
+/* FUNCTIONS ***************************************************************/
+
+VOID
+ScmStartRpcServer(VOID)
+{
+ RPC_STATUS Status;
+
+ DPRINT("ScmStartRpcServer() called\n");
+
+ Status = RpcServerUseProtseqEpW(L"ncacn_np",
+ 10,
+ L"\\pipe\\ntsvcs",
+ NULL);
+ if (Status != RPC_S_OK)
+ {
+ DPRINT1("RpcServerUseProtseqEpW() failed (Status %lx)\n", Status);
+ return;
+ }
+
+ Status = RpcServerRegisterIf(svcctl_v2_0_s_ifspec,
+ NULL,
+ NULL);
+ if (Status != RPC_S_OK)
+ {
+ DPRINT1("RpcServerRegisterIf() failed (Status %lx)\n", Status);
+ return;
+ }
+
+ Status = RpcServerListen(1, 20, TRUE);
+ if (Status != RPC_S_OK)
+ {
+ DPRINT1("RpcServerListen() failed (Status %lx)\n", Status);
+ return;
+ }
+
+ DPRINT("ScmStartRpcServer() done\n");
+}
+
+
+static DWORD
+ScmCreateManagerHandle(LPWSTR lpDatabaseName,
+ SC_HANDLE *Handle)
+{
+ PMANAGER_HANDLE Ptr;
+
+ if (lpDatabaseName == NULL)
+ lpDatabaseName = SERVICES_ACTIVE_DATABASEW;
+
+ if (_wcsicmp(lpDatabaseName, SERVICES_FAILED_DATABASEW) == 0)
+ {
+ DPRINT("Database %S, does not exist\n",lpDatabaseName);
+ return ERROR_DATABASE_DOES_NOT_EXIST;
+ }
+ else if (_wcsicmp(lpDatabaseName, SERVICES_ACTIVE_DATABASEW) != 0)
+ {
+ DPRINT("Invalid Database name %S.\n",lpDatabaseName);
+ return ERROR_INVALID_NAME;
+ }
+
+ Ptr = (MANAGER_HANDLE*) HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(MANAGER_HANDLE) + (wcslen(lpDatabaseName) + 1) * sizeof(WCHAR));
+ if (Ptr == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ Ptr->Handle.Tag = MANAGER_TAG;
+
+ wcscpy(Ptr->DatabaseName, lpDatabaseName);
+
+ *Handle = (SC_HANDLE)Ptr;
+
+ return ERROR_SUCCESS;
+}
+
+
+static DWORD
+ScmCreateServiceHandle(PSERVICE lpServiceEntry,
+ SC_HANDLE *Handle)
+{
+ PSERVICE_HANDLE Ptr;
+
+ Ptr = (SERVICE_HANDLE*) HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ sizeof(SERVICE_HANDLE));
+ if (Ptr == NULL)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ Ptr->Handle.Tag = SERVICE_TAG;
+
+ Ptr->ServiceEntry = lpServiceEntry;
+
+ *Handle = (SC_HANDLE)Ptr;
+
+ return ERROR_SUCCESS;
+}
+
+
+static PMANAGER_HANDLE
+ScmGetServiceManagerFromHandle(SC_RPC_HANDLE Handle)
+{
+ PMANAGER_HANDLE pManager = NULL;
+
+ _SEH2_TRY
+ {
+ if (((PMANAGER_HANDLE)Handle)->Handle.Tag == MANAGER_TAG)
+ pManager = (PMANAGER_HANDLE)Handle;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ DPRINT1("Exception: Invalid Service Manager handle!\n");
+ }
+ _SEH2_END;
+
+ return pManager;
+}
+
+
+static PSERVICE_HANDLE
+ScmGetServiceFromHandle(SC_RPC_HANDLE Handle)
+{
+ PSERVICE_HANDLE pService = NULL;
+
+ _SEH2_TRY
+ {
+ if (((PSERVICE_HANDLE)Handle)->Handle.Tag == SERVICE_TAG)
+ pService = (PSERVICE_HANDLE)Handle;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ DPRINT1("Exception: Invalid Service handle!\n");
+ }
+ _SEH2_END;
+
+ return pService;
+}
+
+
+static DWORD
+ScmCheckAccess(SC_HANDLE Handle,
+ DWORD dwDesiredAccess)
+{
+ PMANAGER_HANDLE hMgr;
+
+ hMgr = (PMANAGER_HANDLE)Handle;
+ if (hMgr->Handle.Tag == MANAGER_TAG)
+ {
+ RtlMapGenericMask(&dwDesiredAccess,
+ &ScmManagerMapping);
+
+ hMgr->Handle.DesiredAccess = dwDesiredAccess;
+
+ return ERROR_SUCCESS;
+ }
+ else if (hMgr->Handle.Tag == SERVICE_TAG)
+ {
+ RtlMapGenericMask(&dwDesiredAccess,
+ &ScmServiceMapping);
+
+ hMgr->Handle.DesiredAccess = dwDesiredAccess;
+
+ return ERROR_SUCCESS;
+ }
+
+ return ERROR_INVALID_HANDLE;
+}
+
+
+DWORD
+ScmAssignNewTag(PSERVICE lpService)
+{
+ /* FIXME */
+ DPRINT("Assigning new tag to service %S\n", lpService->lpServiceName);
+ lpService->dwTag = 0;
+ return ERROR_SUCCESS;
+}
+
+
+/* Internal recursive function */
+/* Need to search for every dependency on every service */
+static DWORD
+Int_EnumDependentServicesW(HKEY hServicesKey,
+ PSERVICE lpService,
+ DWORD dwServiceState,
+ PSERVICE *lpServices,
+ LPDWORD pcbBytesNeeded,
+ LPDWORD lpServicesReturned)
+{
+ DWORD dwError = ERROR_SUCCESS;
+ WCHAR szNameBuf[MAX_PATH];
+ WCHAR szValueBuf[MAX_PATH];
+ WCHAR *lpszNameBuf = szNameBuf;
+ WCHAR *lpszValueBuf = szValueBuf;
+ DWORD dwSize;
+ DWORD dwNumSubKeys;
+ DWORD dwIteration;
+ PSERVICE lpCurrentService;
+ HKEY hServiceEnumKey;
+ DWORD dwCurrentServiceState = SERVICE_ACTIVE;
+ DWORD dwDependServiceStrPtr = 0;
+ DWORD dwRequiredSize = 0;
+
+ /* Get the number of service keys */
+ dwError = RegQueryInfoKeyW(hServicesKey,
+ NULL,
+ NULL,
+ NULL,
+ &dwNumSubKeys,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT("ERROR! Unable to get number of services keys.\n");
+ return dwError;
+ }
+
+ /* Iterate the service keys to see if another service depends on the this service */
+ for (dwIteration = 0; dwIteration < dwNumSubKeys; dwIteration++)
+ {
+ dwSize = MAX_PATH;
+ dwError = RegEnumKeyExW(hServicesKey,
+ dwIteration,
+ lpszNameBuf,
+ &dwSize,
+ NULL,
+ NULL,
+ NULL,
+ NULL);
+ if (dwError != ERROR_SUCCESS)
+ return dwError;
+
+ /* Open the Service key */
+ dwError = RegOpenKeyExW(hServicesKey,
+ lpszNameBuf,
+ 0,
+ KEY_READ,
+ &hServiceEnumKey);
+ if (dwError != ERROR_SUCCESS)
+ return dwError;
+
+ dwSize = MAX_PATH;
+
+ /* Check for the DependOnService Value */
+ dwError = RegQueryValueExW(hServiceEnumKey,
+ L"DependOnService",
+ NULL,
+ NULL,
+ (LPBYTE)lpszValueBuf,
+ &dwSize);
+
+ /* FIXME: Handle load order. */
+
+ /* If the service found has a DependOnService value */
+ if (dwError == ERROR_SUCCESS)
+ {
+ dwDependServiceStrPtr = 0;
+
+ /* Can be more than one Dependencies in the DependOnService string */
+ while (wcslen(lpszValueBuf + dwDependServiceStrPtr) > 0)
+ {
+ if (_wcsicmp(lpszValueBuf + dwDependServiceStrPtr, lpService->lpServiceName) == 0)
+ {
+ /* Get the current enumed service pointer */
+ lpCurrentService = ScmGetServiceEntryByName(lpszNameBuf);
+
+ /* Check for valid Service */
+ if (!lpCurrentService)
+ {
+ /* This should never happen! */
+ DPRINT("This should not happen at this point, report to Developer\n");
+ return ERROR_NOT_FOUND;
+ }
+
+ /* Determine state the service is in */
+ if (lpCurrentService->Status.dwCurrentState == SERVICE_STOPPED)
+ dwCurrentServiceState = SERVICE_INACTIVE;
+
+ /* If the ServiceState matches that requested or searching for SERVICE_STATE_ALL */
+ if ((dwCurrentServiceState == dwServiceState) ||
+ (dwServiceState == SERVICE_STATE_ALL))
+ {
+ /* Calculate the required size */
+ dwRequiredSize += sizeof(SERVICE_STATUS);
+ dwRequiredSize += ((wcslen(lpCurrentService->lpServiceName) + 1) * sizeof(WCHAR));
+ dwRequiredSize += ((wcslen(lpCurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
+
+ /* Add the size for service name and display name pointers */
+ dwRequiredSize += (2 * sizeof(PVOID));
+
+ /* increase the BytesNeeded size */
+ *pcbBytesNeeded = *pcbBytesNeeded + dwRequiredSize;
+
+ /* Don't fill callers buffer yet, as MSDN read that the last service with dependency
+ comes first */
+
+ /* Recursive call to check for its dependencies */
+ Int_EnumDependentServicesW(hServicesKey,
+ lpCurrentService,
+ dwServiceState,
+ lpServices,
+ pcbBytesNeeded,
+ lpServicesReturned);
+
+ /* If the lpServices is valid set the service pointer */
+ if (lpServices)
+ lpServices[*lpServicesReturned] = lpCurrentService;
+
+ *lpServicesReturned = *lpServicesReturned + 1;
+ }
+ }
+
+ dwDependServiceStrPtr += (wcslen(lpszValueBuf + dwDependServiceStrPtr) + 1);
+ }
+ }
+ else if (*pcbBytesNeeded)
+ {
+ dwError = ERROR_SUCCESS;
+ }
+
+ RegCloseKey(hServiceEnumKey);
+ }
+
+ return dwError;
+}
+
+
+/* Function 0 */
+DWORD RCloseServiceHandle(
+ LPSC_RPC_HANDLE hSCObject)
+{
+ PMANAGER_HANDLE hManager;
+ PSERVICE_HANDLE hService;
+ PSERVICE lpService;
+ HKEY hServicesKey;
+ DWORD dwError;
+ DWORD pcbBytesNeeded = 0;
+ DWORD dwServicesReturned = 0;
+
+ DPRINT("RCloseServiceHandle() called\n");
+
+ DPRINT("hSCObject = %p\n", *hSCObject);
+
+ if (*hSCObject == 0)
+ return ERROR_INVALID_HANDLE;
+
+ hManager = ScmGetServiceManagerFromHandle(*hSCObject);
+ hService = ScmGetServiceFromHandle(*hSCObject);
+
+ if (hManager != NULL)
+ {
+ DPRINT("Found manager handle\n");
+
+ /* FIXME: add handle cleanup code */
+
+ HeapFree(GetProcessHeap(), 0, hManager);
+ hManager = NULL;
+
+ DPRINT("RCloseServiceHandle() done\n");
+ return ERROR_SUCCESS;
+ }
+ else if (hService != NULL)
+ {
+ DPRINT("Found service handle\n");
+
+ /* Get the pointer to the service record */
+ lpService = hService->ServiceEntry;
+
+ /* FIXME: add handle cleanup code */
+
+ /* Free the handle */
+ HeapFree(GetProcessHeap(), 0, hService);
+ hService = NULL;
+
+ ASSERT(lpService->dwRefCount > 0);
+
+ lpService->dwRefCount--;
+ DPRINT("CloseServiceHandle - lpService->dwRefCount %u\n",
+ lpService->dwRefCount);
+
+ if (lpService->dwRefCount == 0)
+ {
+ /* If this service has been marked for deletion */
+ if (lpService->bDeleted)
+ {
+ /* Open the Services Reg key */
+ dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ L"System\\CurrentControlSet\\Services",
+ 0,
+ KEY_SET_VALUE | KEY_READ,
+ &hServicesKey);
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT("Failed to open services key\n");
+ return dwError;
+ }
+
+ /* Call the internal function with NULL, just to get bytes we need */
+ Int_EnumDependentServicesW(hServicesKey,
+ lpService,
+ SERVICE_ACTIVE,
+ NULL,
+ &pcbBytesNeeded,
+ &dwServicesReturned);
+
+ /* if pcbBytesNeeded returned a value then there are services running that are dependent on this service*/
+ if (pcbBytesNeeded)
+ {
+ DPRINT("Deletion failed due to running dependencies.\n");
+ RegCloseKey(hServicesKey);
+ return ERROR_SUCCESS;
+ }
+
+ /* There are no references and no runnning dependencies,
+ it is now safe to delete the service */
+
+ /* Delete the Service Key */
+ dwError = RegDeleteKeyW(hServicesKey,
+ lpService->lpServiceName);
+
+ RegCloseKey(hServicesKey);
+
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT("Failed to Delete the Service Registry key\n");
+ return dwError;
+ }
+
+ /* Delete the Service */
+ ScmDeleteServiceRecord(lpService);
+ }
+ }
+
+ DPRINT("RCloseServiceHandle() done\n");
+ return ERROR_SUCCESS;
+ }
+
+ DPRINT("Invalid handle tag (Tag %lx)\n", hManager->Handle.Tag);
+
+ return ERROR_INVALID_HANDLE;
+}
+
+
+/* Function 1 */
+DWORD RControlService(
+ SC_RPC_HANDLE hService,
+ DWORD dwControl,
+ LPSERVICE_STATUS lpServiceStatus)
+{
+ PSERVICE_HANDLE hSvc;
+ PSERVICE lpService;
+ ACCESS_MASK DesiredAccess;
+ DWORD dwError = ERROR_SUCCESS;
+ DWORD pcbBytesNeeded = 0;
+ DWORD dwServicesReturned = 0;
+ DWORD dwControlsAccepted;
+ DWORD dwCurrentState;
+ HKEY hServicesKey = NULL;
+
+ DPRINT("RControlService() called\n");
+
+ if (ScmShutdown)
+ return ERROR_SHUTDOWN_IN_PROGRESS;
+
+ /* Check the service handle */
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
+ {
+ DPRINT1("Invalid service handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+
+ /* Check the service entry point */
+ lpService = hSvc->ServiceEntry;
+ if (lpService == NULL)
+ {
+ DPRINT1("lpService == NULL!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ /* Check access rights */
+ switch (dwControl)
+ {
+ case SERVICE_CONTROL_STOP:
+ DesiredAccess = SERVICE_STOP;
+ break;
+
+ case SERVICE_CONTROL_PAUSE:
+ case SERVICE_CONTROL_CONTINUE:
+ DesiredAccess = SERVICE_PAUSE_CONTINUE;
+ break;
+
+ case SERVICE_INTERROGATE:
+ DesiredAccess = SERVICE_INTERROGATE;
+ break;
+
+ default:
+ if (dwControl >= 128 && dwControl <= 255)
+ DesiredAccess = SERVICE_USER_DEFINED_CONTROL;
+ else
+ DesiredAccess = SERVICE_QUERY_CONFIG |
+ SERVICE_CHANGE_CONFIG |
+ SERVICE_QUERY_STATUS |
+ SERVICE_START |
+ SERVICE_PAUSE_CONTINUE;
+ break;
+ }
+
+ if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
+ DesiredAccess))
+ return ERROR_ACCESS_DENIED;
+
+ if (dwControl == SERVICE_CONTROL_STOP)
+ {
+ /* Check if the service has dependencies running as windows
+ doesn't stop a service that does */
+
+ /* Open the Services Reg key */
+ dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ L"System\\CurrentControlSet\\Services",
+ 0,
+ KEY_READ,
+ &hServicesKey);
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT("Failed to open services key\n");
+ return dwError;
+ }
+
+ /* Call the internal function with NULL, just to get bytes we need */
+ Int_EnumDependentServicesW(hServicesKey,
+ lpService,
+ SERVICE_ACTIVE,
+ NULL,
+ &pcbBytesNeeded,
+ &dwServicesReturned);
+
+ RegCloseKey(hServicesKey);
+
+ /* If pcbBytesNeeded is not zero then there are services running that
+ are dependent on this service */
+ if (pcbBytesNeeded != 0)
+ {
+ DPRINT("Service has running dependencies. Failed to stop service.\n");
+ return ERROR_DEPENDENT_SERVICES_RUNNING;
+ }
+ }
+
+ if (lpService->Status.dwServiceType & SERVICE_DRIVER)
+ {
+ /* Send control code to the driver */
+ dwError = ScmControlDriver(lpService,
+ dwControl,
+ lpServiceStatus);
+ }
+ else
+ {
+ dwControlsAccepted = lpService->Status.dwControlsAccepted;
+ dwCurrentState = lpService->Status.dwCurrentState;
+
+ /* Check the current state before sending a control request */
+ switch (dwCurrentState)
+ {
+ case SERVICE_STOP_PENDING:
+ case SERVICE_STOPPED:
+ return ERROR_SERVICE_CANNOT_ACCEPT_CTRL;
+
+ case SERVICE_START_PENDING:
+ switch (dwControl)
+ {
+ case SERVICE_CONTROL_STOP:
+ break;
+
+ case SERVICE_CONTROL_INTERROGATE:
+ RtlCopyMemory(lpServiceStatus,
+ &lpService->Status,
+ sizeof(SERVICE_STATUS));
+ return ERROR_SUCCESS;
+
+ default:
+ return ERROR_SERVICE_CANNOT_ACCEPT_CTRL;
+ }
+ break;
+ }
+
+ /* Check if the control code is acceptable to the service */
+ switch (dwControl)
+ {
+ case SERVICE_CONTROL_STOP:
+ if ((dwControlsAccepted & SERVICE_ACCEPT_STOP) == 0)
+ return ERROR_INVALID_SERVICE_CONTROL;
+ break;
+
+ case SERVICE_CONTROL_PAUSE:
+ case SERVICE_CONTROL_CONTINUE:
+ if ((dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE) == 0)
+ return ERROR_INVALID_SERVICE_CONTROL;
+ break;
+ }
+
+ /* Send control code to the service */
+ dwError = ScmControlService(lpService,
+ dwControl);
+
+ /* Return service status information */
+ RtlCopyMemory(lpServiceStatus,
+ &lpService->Status,
+ sizeof(SERVICE_STATUS));
+ }
+
+ if ((dwError == ERROR_SUCCESS) && (pcbBytesNeeded))
+ dwError = ERROR_DEPENDENT_SERVICES_RUNNING;
+
+ if (dwError == ERROR_SUCCESS &&
+ dwControl == SERVICE_CONTROL_STOP &&
+ lpServiceStatus->dwCurrentState == SERVICE_STOPPED)
+ {
+ lpService->ProcessId = 0; /* FIXME */
+ lpService->ThreadId = 0;
+ }
+
+
+ return dwError;
+}
+
+
+/* Function 2 */
+DWORD RDeleteService(
+ SC_RPC_HANDLE hService)
+{
+ PSERVICE_HANDLE hSvc;
+ PSERVICE lpService;
+ DWORD dwError;
+
+ DPRINT("RDeleteService() called\n");
+
+ if (ScmShutdown)
+ return ERROR_SHUTDOWN_IN_PROGRESS;
+
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
+ {
+ DPRINT1("Invalid service handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
+ DELETE))
+ return ERROR_ACCESS_DENIED;
+
+ lpService = hSvc->ServiceEntry;
+ if (lpService == NULL)
+ {
+ DPRINT("lpService == NULL!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ /* FIXME: Acquire service database lock exclusively */
+
+ if (lpService->bDeleted)
+ {
+ DPRINT("The service has already been marked for delete!\n");
+ return ERROR_SERVICE_MARKED_FOR_DELETE;
+ }
+
+ /* Mark service for delete */
+ lpService->bDeleted = TRUE;
+
+ dwError = ScmMarkServiceForDelete(lpService);
+
+ /* FIXME: Release service database lock */
+
+ DPRINT("RDeleteService() done\n");
+
+ return dwError;
+}
+
+
+/* Function 3 */
+DWORD RLockServiceDatabase(
+ SC_RPC_HANDLE hSCManager,
+ LPSC_RPC_LOCK lpLock)
+{
+ PMANAGER_HANDLE hMgr;
+
+ DPRINT("RLockServiceDatabase() called\n");
+
+ *lpLock = 0;
+
+ hMgr = ScmGetServiceManagerFromHandle(hSCManager);
+ if (hMgr == NULL)
+ {
+ DPRINT1("Invalid service manager handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ if (!RtlAreAllAccessesGranted(hMgr->Handle.DesiredAccess,
+ SC_MANAGER_LOCK))
+ return ERROR_ACCESS_DENIED;
+
+// return ScmLockDatabase(0, hMgr->0xC, hLock);
+
+ /* FIXME: Lock the database */
+ *lpLock = (SC_RPC_LOCK)0x12345678; /* Dummy! */
+
+ return ERROR_SUCCESS;
+}
+
+
+/* Function 4 */
+DWORD RQueryServiceObjectSecurity(
+ SC_RPC_HANDLE hService,
+ SECURITY_INFORMATION dwSecurityInformation,
+ LPBYTE lpSecurityDescriptor,
+ DWORD cbBufSize,
+ LPBOUNDED_DWORD_256K pcbBytesNeeded)
+{
+ PSERVICE_HANDLE hSvc;
+ PSERVICE lpService;
+ ULONG DesiredAccess = 0;
+ NTSTATUS Status;
+ DWORD dwBytesNeeded;
+ DWORD dwError;
+
+
+ SECURITY_DESCRIPTOR ObjectDescriptor;
+
+ DPRINT("RQueryServiceObjectSecurity() called\n");
+
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
+ {
+ DPRINT1("Invalid service handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
++ if (dwSecurityInformation & (DACL_SECURITY_INFORMATION |
++ GROUP_SECURITY_INFORMATION |
+ OWNER_SECURITY_INFORMATION))
+ DesiredAccess |= READ_CONTROL;
+
+ if (dwSecurityInformation & SACL_SECURITY_INFORMATION)
+ DesiredAccess |= ACCESS_SYSTEM_SECURITY;
+
+ if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
+ DesiredAccess))
+ {
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ return ERROR_ACCESS_DENIED;
+ }
+
+ lpService = hSvc->ServiceEntry;
+ if (lpService == NULL)
+ {
+ DPRINT("lpService == NULL!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ /* FIXME: Lock the service list */
+
+ /* hack */
+ Status = RtlCreateSecurityDescriptor(&ObjectDescriptor, SECURITY_DESCRIPTOR_REVISION);
+
+ Status = RtlQuerySecurityObject(&ObjectDescriptor /* lpService->lpSecurityDescriptor */,
+ dwSecurityInformation,
+ (PSECURITY_DESCRIPTOR)lpSecurityDescriptor,
+ cbBufSize,
+ &dwBytesNeeded);
+
+ /* FIXME: Unlock the service list */
+
+ if (NT_SUCCESS(Status))
+ {
+ *pcbBytesNeeded = dwBytesNeeded;
+ dwError = STATUS_SUCCESS;
+ }
+ else if (Status == STATUS_BUFFER_TOO_SMALL)
+ {
+ *pcbBytesNeeded = dwBytesNeeded;
+ dwError = ERROR_INSUFFICIENT_BUFFER;
+ }
+ else if (Status == STATUS_BAD_DESCRIPTOR_FORMAT)
+ {
+ dwError = ERROR_GEN_FAILURE;
+ }
+ else
+ {
+ dwError = RtlNtStatusToDosError(Status);
+ }
+
+ return dwError;
+}
+
+
+/* Function 5 */
+DWORD RSetServiceObjectSecurity(
+ SC_RPC_HANDLE hService,
+ DWORD dwSecurityInformation,
+ LPBYTE lpSecurityDescriptor,
+ DWORD dwSecuityDescriptorSize)
+{
+ PSERVICE_HANDLE hSvc;
+ PSERVICE lpService;
+ ULONG DesiredAccess = 0;
+ /* HANDLE hToken = NULL; */
+ HKEY hServiceKey;
+ /* NTSTATUS Status; */
+ DWORD dwError;
+
+ DPRINT("RSetServiceObjectSecurity() called\n");
+
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
+ {
+ DPRINT1("Invalid service handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ if (dwSecurityInformation == 0 ||
+ dwSecurityInformation & ~(OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION
+ | DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION))
+ return ERROR_INVALID_PARAMETER;
+
+ if (!RtlValidSecurityDescriptor((PSECURITY_DESCRIPTOR)lpSecurityDescriptor))
+ return ERROR_INVALID_PARAMETER;
+
+ if (dwSecurityInformation & SACL_SECURITY_INFORMATION)
+ DesiredAccess |= ACCESS_SYSTEM_SECURITY;
+
+ if (dwSecurityInformation & DACL_SECURITY_INFORMATION)
+ DesiredAccess |= WRITE_DAC;
+
+ if (dwSecurityInformation & (OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION))
+ DesiredAccess |= WRITE_OWNER;
+
+ if ((dwSecurityInformation & OWNER_SECURITY_INFORMATION) &&
+ (((PISECURITY_DESCRIPTOR)lpSecurityDescriptor)->Owner == NULL))
+ return ERROR_INVALID_PARAMETER;
+
+ if ((dwSecurityInformation & GROUP_SECURITY_INFORMATION) &&
+ (((PISECURITY_DESCRIPTOR)lpSecurityDescriptor)->Group == NULL))
+ return ERROR_INVALID_PARAMETER;
+
+ if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
+ DesiredAccess))
+ {
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ return ERROR_ACCESS_DENIED;
+ }
+
+ lpService = hSvc->ServiceEntry;
+ if (lpService == NULL)
+ {
+ DPRINT("lpService == NULL!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ if (lpService->bDeleted)
+ return ERROR_SERVICE_MARKED_FOR_DELETE;
+
+#if 0
+ RpcImpersonateClient(NULL);
+
+ Status = NtOpenThreadToken(NtCurrentThread(),
+ 8,
+ TRUE,
+ &hToken);
+ if (!NT_SUCCESS(Status))
+ return RtlNtStatusToDosError(Status);
+
+ RpcRevertToSelf();
+
+ /* FIXME: Lock service database */
+
+ Status = RtlSetSecurityObject(dwSecurityInformation,
+ (PSECURITY_DESCRIPTOR)lpSecurityDescriptor,
+ &lpService->lpSecurityDescriptor,
+ &ScmServiceMapping,
+ hToken);
+ if (!NT_SUCCESS(Status))
+ {
+ dwError = RtlNtStatusToDosError(Status);
+ goto Done;
+ }
+#endif
+
+ dwError = ScmOpenServiceKey(lpService->lpServiceName,
+ READ_CONTROL | KEY_CREATE_SUB_KEY | KEY_SET_VALUE,
+ &hServiceKey);
+ if (dwError != ERROR_SUCCESS)
+ goto Done;
+
+ UNIMPLEMENTED;
+ dwError = ERROR_SUCCESS;
+// dwError = ScmWriteSecurityDescriptor(hServiceKey,
+// lpService->lpSecurityDescriptor);
+
+ RegFlushKey(hServiceKey);
+ RegCloseKey(hServiceKey);
+
+Done:
+
+#if 0
+ if (hToken != NULL)
+ NtClose(hToken);
+#endif
+
+ /* FIXME: Unlock service database */
+
+ DPRINT("RSetServiceObjectSecurity() done (Error %lu)\n", dwError);
+
+ return dwError;
+}
+
+
+/* Function 6 */
+DWORD RQueryServiceStatus(
+ SC_RPC_HANDLE hService,
+ LPSERVICE_STATUS lpServiceStatus)
+{
+ PSERVICE_HANDLE hSvc;
+ PSERVICE lpService;
+
+ DPRINT("RQueryServiceStatus() called\n");
+
+ if (ScmShutdown)
+ return ERROR_SHUTDOWN_IN_PROGRESS;
+
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
+ {
+ DPRINT1("Invalid service handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
+ SERVICE_QUERY_STATUS))
+ {
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ return ERROR_ACCESS_DENIED;
+ }
+
+ lpService = hSvc->ServiceEntry;
+ if (lpService == NULL)
+ {
+ DPRINT("lpService == NULL!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ ScmLockDatabaseShared();
+
+ /* Return service status information */
+ RtlCopyMemory(lpServiceStatus,
+ &lpService->Status,
+ sizeof(SERVICE_STATUS));
+
+ ScmUnlockDatabase();
+
+ return ERROR_SUCCESS;
+}
+
+
+static BOOL
+ScmIsValidServiceState(DWORD dwCurrentState)
+{
+ switch (dwCurrentState)
+ {
+ case SERVICE_STOPPED:
+ case SERVICE_START_PENDING:
+ case SERVICE_STOP_PENDING:
+ case SERVICE_RUNNING:
+ case SERVICE_CONTINUE_PENDING:
+ case SERVICE_PAUSE_PENDING:
+ case SERVICE_PAUSED:
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+}
+
+
+/* Function 7 */
+DWORD RSetServiceStatus(
+ RPC_SERVICE_STATUS_HANDLE hServiceStatus,
+ LPSERVICE_STATUS lpServiceStatus)
+{
+ PSERVICE lpService;
+
+ DPRINT("RSetServiceStatus() called\n");
+ DPRINT("hServiceStatus = %p\n", hServiceStatus);
+ DPRINT("dwServiceType = %lu\n", lpServiceStatus->dwServiceType);
+ DPRINT("dwCurrentState = %lu\n", lpServiceStatus->dwCurrentState);
+ DPRINT("dwControlsAccepted = %lu\n", lpServiceStatus->dwControlsAccepted);
+ DPRINT("dwWin32ExitCode = %lu\n", lpServiceStatus->dwWin32ExitCode);
+ DPRINT("dwServiceSpecificExitCode = %lu\n", lpServiceStatus->dwServiceSpecificExitCode);
+ DPRINT("dwCheckPoint = %lu\n", lpServiceStatus->dwCheckPoint);
+ DPRINT("dwWaitHint = %lu\n", lpServiceStatus->dwWaitHint);
+
+ if (hServiceStatus == 0)
+ {
+ DPRINT("hServiceStatus == NULL!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ lpService = (PSERVICE)hServiceStatus;
+ if (lpService == NULL)
+ {
+ DPRINT("lpService == NULL!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ /* Check current state */
+ if (!ScmIsValidServiceState(lpServiceStatus->dwCurrentState))
+ {
+ DPRINT("Invalid service state!\n");
+ return ERROR_INVALID_DATA;
+ }
+
+ /* Check service type */
+ if (!(lpServiceStatus->dwServiceType & SERVICE_WIN32) &&
+ (lpServiceStatus->dwServiceType & SERVICE_DRIVER))
+ {
+ DPRINT("Invalid service type!\n");
+ return ERROR_INVALID_DATA;
+ }
+
+ /* Check accepted controls */
+ if (lpServiceStatus->dwControlsAccepted & ~0xFF)
+ {
+ DPRINT("Invalid controls accepted!\n");
+ return ERROR_INVALID_DATA;
+ }
+
+ ScmLockDatabaseExclusive();
+
+ RtlCopyMemory(&lpService->Status,
+ lpServiceStatus,
+ sizeof(SERVICE_STATUS));
+
+ ScmUnlockDatabase();
+
+ DPRINT("Set %S to %lu\n", lpService->lpDisplayName, lpService->Status.dwCurrentState);
+ DPRINT("RSetServiceStatus() done\n");
+
+ return ERROR_SUCCESS;
+}
+
+
+/* Function 8 */
+DWORD RUnlockServiceDatabase(
+ LPSC_RPC_LOCK Lock)
+{
+ UNIMPLEMENTED;
+ return ERROR_SUCCESS;
+}
+
+
+/* Function 9 */
+DWORD RNotifyBootConfigStatus(
+ SVCCTL_HANDLEW lpMachineName,
+ DWORD BootAcceptable)
+{
+ UNIMPLEMENTED;
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 10 */
+DWORD RI_ScSetServiceBitsW(
+ RPC_SERVICE_STATUS_HANDLE hServiceStatus,
+ DWORD dwServiceBits,
+ int bSetBitsOn,
+ int bUpdateImmediately,
+ wchar_t *lpString)
+{
+ UNIMPLEMENTED;
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 11 */
+DWORD RChangeServiceConfigW(
+ SC_RPC_HANDLE hService,
+ DWORD dwServiceType,
+ DWORD dwStartType,
+ DWORD dwErrorControl,
+ LPWSTR lpBinaryPathName,
+ LPWSTR lpLoadOrderGroup,
+ LPDWORD lpdwTagId,
+ LPBYTE lpDependencies,
+ DWORD dwDependSize,
+ LPWSTR lpServiceStartName,
+ LPBYTE lpPassword,
+ DWORD dwPwSize,
+ LPWSTR lpDisplayName)
+{
+ DWORD dwError = ERROR_SUCCESS;
+ PSERVICE_HANDLE hSvc;
+ PSERVICE lpService = NULL;
+ HKEY hServiceKey = NULL;
+ LPWSTR lpDisplayNameW = NULL;
+
+ DPRINT("RChangeServiceConfigW() called\n");
+ DPRINT("dwServiceType = %lu\n", dwServiceType);
+ DPRINT("dwStartType = %lu\n", dwStartType);
+ DPRINT("dwErrorControl = %lu\n", dwErrorControl);
+ DPRINT("lpBinaryPathName = %S\n", lpBinaryPathName);
+ DPRINT("lpLoadOrderGroup = %S\n", lpLoadOrderGroup);
+ DPRINT("lpDisplayName = %S\n", lpDisplayName);
+
+ if (ScmShutdown)
+ return ERROR_SHUTDOWN_IN_PROGRESS;
+
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
+ {
+ DPRINT1("Invalid service handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
+ SERVICE_CHANGE_CONFIG))
+ {
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ return ERROR_ACCESS_DENIED;
+ }
+
+ lpService = hSvc->ServiceEntry;
+ if (lpService == NULL)
+ {
+ DPRINT("lpService == NULL!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ /* FIXME: Lock database exclusively */
+
+ if (lpService->bDeleted)
+ {
+ /* FIXME: Unlock database */
+ DPRINT("The service has already been marked for delete!\n");
+ return ERROR_SERVICE_MARKED_FOR_DELETE;
+ }
+
+ /* Open the service key */
+ dwError = ScmOpenServiceKey(lpService->szServiceName,
+ KEY_SET_VALUE,
+ &hServiceKey);
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+
+ /* Write service data to the registry */
+ /* Set the display name */
+ if (lpDisplayName != NULL && *lpDisplayName != 0)
+ {
+ RegSetValueExW(hServiceKey,
+ L"DisplayName",
+ 0,
+ REG_SZ,
+ (LPBYTE)lpDisplayName,
+ (wcslen(lpDisplayName) + 1) * sizeof(WCHAR));
+
+ /* Update the display name */
+ lpDisplayNameW = (LPWSTR)HeapAlloc(GetProcessHeap(),
+ 0,
+ (wcslen(lpDisplayName) + 1) * sizeof(WCHAR));
+ if (lpDisplayNameW == NULL)
+ {
+ dwError = ERROR_NOT_ENOUGH_MEMORY;
+ goto done;
+ }
+
+ if (lpService->lpDisplayName != lpService->lpServiceName)
+ HeapFree(GetProcessHeap(), 0, lpService->lpDisplayName);
+
+ lpService->lpDisplayName = lpDisplayNameW;
+ }
+
+ if (dwServiceType != SERVICE_NO_CHANGE)
+ {
+ /* Set the service type */
+ dwError = RegSetValueExW(hServiceKey,
+ L"Type",
+ 0,
+ REG_DWORD,
+ (LPBYTE)&dwServiceType,
+ sizeof(DWORD));
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+
+ lpService->Status.dwServiceType = dwServiceType;
+ }
+
+ if (dwStartType != SERVICE_NO_CHANGE)
+ {
+ /* Set the start value */
+ dwError = RegSetValueExW(hServiceKey,
+ L"Start",
+ 0,
+ REG_DWORD,
+ (LPBYTE)&dwStartType,
+ sizeof(DWORD));
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+
+ lpService->dwStartType = dwStartType;
+ }
+
+ if (dwErrorControl != SERVICE_NO_CHANGE)
+ {
+ /* Set the error control value */
+ dwError = RegSetValueExW(hServiceKey,
+ L"ErrorControl",
+ 0,
+ REG_DWORD,
+ (LPBYTE)&dwErrorControl,
+ sizeof(DWORD));
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+
+ lpService->dwErrorControl = dwErrorControl;
+ }
+
+#if 0
+ /* FIXME: set the new ImagePath value */
+
+ /* Set the image path */
+ if (dwServiceType & SERVICE_WIN32)
+ {
+ if (lpBinaryPathName != NULL && *lpBinaryPathName != 0)
+ {
+ dwError = RegSetValueExW(hServiceKey,
+ L"ImagePath",
+ 0,
+ REG_EXPAND_SZ,
+ (LPBYTE)lpBinaryPathName,
+ (wcslen(lpBinaryPathName) + 1) * sizeof(WCHAR));
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+ }
+ }
+ else if (dwServiceType & SERVICE_DRIVER)
+ {
+ if (lpImagePath != NULL && *lpImagePath != 0)
+ {
+ dwError = RegSetValueExW(hServiceKey,
+ L"ImagePath",
+ 0,
+ REG_EXPAND_SZ,
+ (LPBYTE)lpImagePath,
+ (wcslen(lpImagePath) + 1) *sizeof(WCHAR));
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+ }
+ }
+#endif
+
+ /* Set the group name */
+ if (lpLoadOrderGroup != NULL && *lpLoadOrderGroup != 0)
+ {
+ dwError = RegSetValueExW(hServiceKey,
+ L"Group",
+ 0,
+ REG_SZ,
+ (LPBYTE)lpLoadOrderGroup,
+ (wcslen(lpLoadOrderGroup) + 1) * sizeof(WCHAR));
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+
+ dwError = ScmSetServiceGroup(lpService,
+ lpLoadOrderGroup);
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+ }
+
+ if (lpdwTagId != NULL)
+ {
+ dwError = ScmAssignNewTag(lpService);
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+
+ dwError = RegSetValueExW(hServiceKey,
+ L"Tag",
+ 0,
+ REG_DWORD,
+ (LPBYTE)&lpService->dwTag,
+ sizeof(DWORD));
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+
+ *lpdwTagId = lpService->dwTag;
+ }
+
+ /* Write dependencies */
+ if (lpDependencies != NULL && *lpDependencies != 0)
+ {
+ dwError = ScmWriteDependencies(hServiceKey,
+ (LPWSTR)lpDependencies,
+ dwDependSize);
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+ }
+
+ if (lpPassword != NULL)
+ {
+ /* FIXME: Write password */
+ }
+
+ /* FIXME: Unlock database */
+
+done:
+ if (hServiceKey != NULL)
+ RegCloseKey(hServiceKey);
+
+ DPRINT("RChangeServiceConfigW() done (Error %lu)\n", dwError);
+
+ return dwError;
+}
+
+
+/* Create a path suitable for the bootloader out of the full path */
+DWORD
+ScmConvertToBootPathName(wchar_t *CanonName, wchar_t **RelativeName)
+{
+ DWORD ServiceNameLen, BufferSize, ExpandedLen;
+ WCHAR Dest;
+ WCHAR *Expanded;
+ UNICODE_STRING NtPathName, SystemRoot, LinkTarget;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ NTSTATUS Status;
+ HANDLE SymbolicLinkHandle;
+
+ DPRINT("ScmConvertToBootPathName %S\n", CanonName);
+
+ ServiceNameLen = wcslen(CanonName);
+
+ /* First check, if it's already good */
+ if (ServiceNameLen > 12 &&
+ !_wcsnicmp(L"\\SystemRoot\\", CanonName, 12))
+ {
+ *RelativeName = LocalAlloc(LMEM_ZEROINIT, ServiceNameLen * sizeof(WCHAR) + sizeof(WCHAR));
+ if (*RelativeName == NULL)
+ {
+ DPRINT("Error allocating memory for boot driver name!\n");
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ /* Copy it */
+ wcscpy(*RelativeName, CanonName);
+
+ DPRINT("Bootdriver name %S\n", *RelativeName);
+ return ERROR_SUCCESS;
+ }
+
+ /* If it has %SystemRoot% prefix, substitute it to \System*/
+ if (ServiceNameLen > 13 &&
+ !_wcsnicmp(L"%SystemRoot%\\", CanonName, 13))
+ {
+ /* There is no +sizeof(wchar_t) because the name is less by 1 wchar */
+ *RelativeName = LocalAlloc(LMEM_ZEROINIT, ServiceNameLen * sizeof(WCHAR));
+
+ if (*RelativeName == NULL)
+ {
+ DPRINT("Error allocating memory for boot driver name!\n");
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ /* Copy it */
+ wcscpy(*RelativeName, L"\\SystemRoot\\");
+ wcscat(*RelativeName, CanonName + 13);
+
+ DPRINT("Bootdriver name %S\n", *RelativeName);
+ return ERROR_SUCCESS;
+ }
+
+ /* Get buffer size needed for expanding env strings */
+ BufferSize = ExpandEnvironmentStringsW(L"%SystemRoot%\\", &Dest, 1);
+
+ if (BufferSize <= 1)
+ {
+ DPRINT("Error during a call to ExpandEnvironmentStringsW()\n");
+ return ERROR_INVALID_ENVIRONMENT;
+ }
+
+ /* Allocate memory, since the size is known now */
+ Expanded = LocalAlloc(LMEM_ZEROINIT, BufferSize * sizeof(WCHAR) + sizeof(WCHAR));
+ if (!Expanded)
+ {
+ DPRINT("Error allocating memory for boot driver name!\n");
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ /* Expand it */
+ if (ExpandEnvironmentStringsW(L"%SystemRoot%\\", Expanded, BufferSize) >
+ BufferSize)
+ {
+ DPRINT("Error during a call to ExpandEnvironmentStringsW()\n");
+ LocalFree(Expanded);
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ /* Convert to NY-style path */
+ if (!RtlDosPathNameToNtPathName_U(Expanded, &NtPathName, NULL, NULL))
+ {
+ DPRINT("Error during a call to RtlDosPathNameToNtPathName_U()\n");
+ return ERROR_INVALID_ENVIRONMENT;
+ }
+
+ DPRINT("Converted to NT-style %wZ\n", &NtPathName);
+
+ /* No need to keep the dos-path anymore */
+ LocalFree(Expanded);
+
+ /* Copy it to the allocated place */
+ Expanded = LocalAlloc(LMEM_ZEROINIT, NtPathName.Length + sizeof(WCHAR));
+ if (!Expanded)
+ {
+ DPRINT("Error allocating memory for boot driver name!\n");
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ ExpandedLen = NtPathName.Length / sizeof(WCHAR);
+ wcsncpy(Expanded, NtPathName.Buffer, ExpandedLen);
+ Expanded[ExpandedLen] = 0;
+
+ if (ServiceNameLen > ExpandedLen &&
+ !_wcsnicmp(Expanded, CanonName, ExpandedLen))
+ {
+ /* Only \SystemRoot\ is missing */
+ *RelativeName = LocalAlloc(LMEM_ZEROINIT,
+ (ServiceNameLen - ExpandedLen) * sizeof(WCHAR) + 13*sizeof(WCHAR));
+ if (*RelativeName == NULL)
+ {
+ DPRINT("Error allocating memory for boot driver name!\n");
+ LocalFree(Expanded);
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ wcscpy(*RelativeName, L"\\SystemRoot\\");
+ wcscat(*RelativeName, CanonName + ExpandedLen);
+
+ RtlFreeUnicodeString(&NtPathName);
+ return ERROR_SUCCESS;
+ }
+
+ /* The most complex case starts here */
+ RtlInitUnicodeString(&SystemRoot, L"\\SystemRoot");
+ InitializeObjectAttributes(&ObjectAttributes,
+ &SystemRoot,
+ OBJ_CASE_INSENSITIVE,
+ NULL,
+ NULL);
+
+ /* Open this symlink */
+ Status = NtOpenSymbolicLinkObject(&SymbolicLinkHandle, SYMBOLIC_LINK_QUERY, &ObjectAttributes);
+
+ if (NT_SUCCESS(Status))
+ {
+ LinkTarget.Length = 0;
+ LinkTarget.MaximumLength = 0;
+
+ DPRINT("Opened symbolic link object\n");
+
+ Status = NtQuerySymbolicLinkObject(SymbolicLinkHandle, &LinkTarget, &BufferSize);
+ if (NT_SUCCESS(Status) || Status == STATUS_BUFFER_TOO_SMALL)
+ {
+ /* Check if required buffer size is sane */
+ if (BufferSize > 0xFFFD)
+ {
+ DPRINT("Too large buffer required\n");
+ *RelativeName = 0;
+
+ if (SymbolicLinkHandle) NtClose(SymbolicLinkHandle);
+ LocalFree(Expanded);
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ /* Alloc the string */
+ LinkTarget.Buffer = LocalAlloc(LMEM_ZEROINIT, BufferSize + sizeof(WCHAR));
+ if (!LinkTarget.Buffer)
+ {
+ DPRINT("Unable to alloc buffer\n");
+ if (SymbolicLinkHandle) NtClose(SymbolicLinkHandle);
+ LocalFree(Expanded);
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ /* Do a real query now */
+ LinkTarget.Length = BufferSize;
+ LinkTarget.MaximumLength = LinkTarget.Length + sizeof(WCHAR);
+
+ Status = NtQuerySymbolicLinkObject(SymbolicLinkHandle, &LinkTarget, &BufferSize);
+ if (NT_SUCCESS(Status))
+ {
+ DPRINT("LinkTarget: %wZ\n", &LinkTarget);
+
+ ExpandedLen = LinkTarget.Length / sizeof(WCHAR);
+ if ((ServiceNameLen > ExpandedLen) &&
+ !_wcsnicmp(LinkTarget.Buffer, CanonName, ExpandedLen))
+ {
+ *RelativeName = LocalAlloc(LMEM_ZEROINIT,
+ (ServiceNameLen - ExpandedLen) * sizeof(WCHAR) + 13*sizeof(WCHAR));
+
+ if (*RelativeName == NULL)
+ {
+ DPRINT("Unable to alloc buffer\n");
+ if (SymbolicLinkHandle) NtClose(SymbolicLinkHandle);
+ LocalFree(Expanded);
+ RtlFreeUnicodeString(&NtPathName);
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ /* Copy it over, substituting the first part
+ with SystemRoot */
+ wcscpy(*RelativeName, L"\\SystemRoot\\");
+ wcscat(*RelativeName, CanonName+ExpandedLen+1);
+
+ /* Cleanup */
+ if (SymbolicLinkHandle) NtClose(SymbolicLinkHandle);
+ LocalFree(Expanded);
+ RtlFreeUnicodeString(&NtPathName);
+
+ /* Return success */
+ return ERROR_SUCCESS;
+ }
+ else
+ {
+ if (SymbolicLinkHandle) NtClose(SymbolicLinkHandle);
+ LocalFree(Expanded);
+ RtlFreeUnicodeString(&NtPathName);
+ return ERROR_INVALID_PARAMETER;
+ }
+ }
+ else
+ {
+ DPRINT("Error, Status = %08X\n", Status);
+ if (SymbolicLinkHandle) NtClose(SymbolicLinkHandle);
+ LocalFree(Expanded);
+ RtlFreeUnicodeString(&NtPathName);
+ return ERROR_INVALID_PARAMETER;
+ }
+ }
+ else
+ {
+ DPRINT("Error, Status = %08X\n", Status);
+ if (SymbolicLinkHandle) NtClose(SymbolicLinkHandle);
+ LocalFree(Expanded);
+ RtlFreeUnicodeString(&NtPathName);
+ return ERROR_INVALID_PARAMETER;
+ }
+ }
+ else
+ {
+ DPRINT("Error, Status = %08X\n", Status);
+ LocalFree(Expanded);
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ /* Failure */
+ *RelativeName = NULL;
+ return ERROR_INVALID_PARAMETER;
+}
+
+DWORD
+ScmCanonDriverImagePath(DWORD dwStartType,
+ const wchar_t *lpServiceName,
+ wchar_t **lpCanonName)
+{
+ DWORD ServiceNameLen, Result;
+ UNICODE_STRING NtServiceName;
+ WCHAR *RelativeName;
+ const WCHAR *SourceName = lpServiceName;
+
+ /* Calculate the length of the service's name */
+ ServiceNameLen = wcslen(lpServiceName);
+
+ /* 12 is wcslen(L"\\SystemRoot\\") */
+ if (ServiceNameLen > 12 &&
+ !_wcsnicmp(L"\\SystemRoot\\", lpServiceName, 12))
+ {
+ /* SystemRoot prefix is already included */
+
+ *lpCanonName = LocalAlloc(LMEM_ZEROINIT, ServiceNameLen * sizeof(WCHAR) + sizeof(WCHAR));
+
+ if (*lpCanonName == NULL)
+ {
+ DPRINT("Error allocating memory for canonized service name!\n");
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ /* If it's a boot-time driver, it must be systemroot relative */
+ if (dwStartType == SERVICE_BOOT_START)
+ SourceName += 12;
+
+ /* Copy it */
+ wcscpy(*lpCanonName, SourceName);
+
+ DPRINT("Canonicalized name %S\n", *lpCanonName);
+ return NO_ERROR;
+ }
+
+ /* Check if it has %SystemRoot% (len=13) */
+ if (ServiceNameLen > 13 &&
+ !_wcsnicmp(L"%%SystemRoot%%\\", lpServiceName, 13))
+ {
+ /* Substitute %SystemRoot% with \\SystemRoot\\ */
+ *lpCanonName = LocalAlloc(LMEM_ZEROINIT, ServiceNameLen * sizeof(WCHAR) + sizeof(WCHAR));
+
+ if (*lpCanonName == NULL)
+ {
+ DPRINT("Error allocating memory for canonized service name!\n");
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ /* If it's a boot-time driver, it must be systemroot relative */
+ if (dwStartType == SERVICE_BOOT_START)
+ wcscpy(*lpCanonName, L"\\SystemRoot\\");
+
+ wcscat(*lpCanonName, lpServiceName + 13);
+
+ DPRINT("Canonicalized name %S\n", *lpCanonName);
+ return NO_ERROR;
+ }
+
+ /* Check if it's a relative path name */
+ if (lpServiceName[0] != L'\\' && lpServiceName[1] != L':')
+ {
+ *lpCanonName = LocalAlloc(LMEM_ZEROINIT, ServiceNameLen * sizeof(WCHAR) + sizeof(WCHAR));
+
+ if (*lpCanonName == NULL)
+ {
+ DPRINT("Error allocating memory for canonized service name!\n");
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ /* Just copy it over without changing */
+ wcscpy(*lpCanonName, lpServiceName);
+
+ return NO_ERROR;
+ }
+
+ /* It seems to be a DOS path, convert it */
+ if (!RtlDosPathNameToNtPathName_U(lpServiceName, &NtServiceName, NULL, NULL))
+ {
+ DPRINT("RtlDosPathNameToNtPathName_U() failed!\n");
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ *lpCanonName = LocalAlloc(LMEM_ZEROINIT, NtServiceName.Length + sizeof(WCHAR));
+
+ if (*lpCanonName == NULL)
+ {
+ DPRINT("Error allocating memory for canonized service name!\n");
+ RtlFreeUnicodeString(&NtServiceName);
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ /* Copy the string */
+ wcsncpy(*lpCanonName, NtServiceName.Buffer, NtServiceName.Length / sizeof(WCHAR));
+
+ /* The unicode string is not needed anymore */
+ RtlFreeUnicodeString(&NtServiceName);
+
+ if (dwStartType != SERVICE_BOOT_START)
+ {
+ DPRINT("Canonicalized name %S\n", *lpCanonName);
+ return NO_ERROR;
+ }
+
+ /* The service is boot-started, so must be relative */
+ Result = ScmConvertToBootPathName(*lpCanonName, &RelativeName);
+ if (Result)
+ {
+ /* There is a problem, free name and return */
+ LocalFree(*lpCanonName);
+ DPRINT("Error converting named!\n");
+ return Result;
+ }
+
+ ASSERT(RelativeName);
+
+ /* Copy that string */
+ wcscpy(*lpCanonName, RelativeName + 12);
+
+ /* Free the allocated buffer */
+ LocalFree(RelativeName);
+
+ DPRINT("Canonicalized name %S\n", *lpCanonName);
+
+ /* Success */
+ return NO_ERROR;
+}
+
+
+/* Function 12 */
+DWORD RCreateServiceW(
+ SC_RPC_HANDLE hSCManager,
+ LPCWSTR lpServiceName,
+ LPCWSTR lpDisplayName,
+ DWORD dwDesiredAccess,
+ DWORD dwServiceType,
+ DWORD dwStartType,
+ DWORD dwErrorControl,
+ LPCWSTR lpBinaryPathName,
+ LPCWSTR lpLoadOrderGroup,
+ LPDWORD lpdwTagId,
+ LPBYTE lpDependencies,
+ DWORD dwDependSize,
+ LPCWSTR lpServiceStartName,
+ LPBYTE lpPassword,
+ DWORD dwPwSize,
+ LPSC_RPC_HANDLE lpServiceHandle)
+{
+ PMANAGER_HANDLE hManager;
+ DWORD dwError = ERROR_SUCCESS;
+ PSERVICE lpService = NULL;
+ SC_HANDLE hServiceHandle = NULL;
+ LPWSTR lpImagePath = NULL;
+ HKEY hServiceKey = NULL;
+ LPWSTR lpObjectName;
+
+ DPRINT("RCreateServiceW() called\n");
+ DPRINT("lpServiceName = %S\n", lpServiceName);
+ DPRINT("lpDisplayName = %S\n", lpDisplayName);
+ DPRINT("dwDesiredAccess = %lx\n", dwDesiredAccess);
+ DPRINT("dwServiceType = %lu\n", dwServiceType);
+ DPRINT("dwStartType = %lu\n", dwStartType);
+ DPRINT("dwErrorControl = %lu\n", dwErrorControl);
+ DPRINT("lpBinaryPathName = %S\n", lpBinaryPathName);
+ DPRINT("lpLoadOrderGroup = %S\n", lpLoadOrderGroup);
+
+ if (ScmShutdown)
+ return ERROR_SHUTDOWN_IN_PROGRESS;
+
+ hManager = ScmGetServiceManagerFromHandle(hSCManager);
+ if (hManager == NULL)
+ {
+ DPRINT1("Invalid service manager handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ /* Check access rights */
+ if (!RtlAreAllAccessesGranted(hManager->Handle.DesiredAccess,
+ SC_MANAGER_CREATE_SERVICE))
+ {
+ DPRINT("Insufficient access rights! 0x%lx\n",
+ hManager->Handle.DesiredAccess);
+ return ERROR_ACCESS_DENIED;
+ }
+
+ if (wcslen(lpServiceName) == 0)
+ {
+ return ERROR_INVALID_NAME;
+ }
+
+ if (wcslen(lpBinaryPathName) == 0)
+ {
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ if ((dwServiceType == (SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS)) &&
+ (lpServiceStartName))
+ {
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ if ((dwServiceType > SERVICE_WIN32_SHARE_PROCESS) &&
+ (dwServiceType != (SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS)) &&
+ (dwServiceType != (SERVICE_WIN32_SHARE_PROCESS | SERVICE_INTERACTIVE_PROCESS)))
+ {
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ if (dwStartType > SERVICE_DISABLED)
+ {
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ lpService = ScmGetServiceEntryByName(lpServiceName);
+ if (lpService)
+ {
+ /* check if it is marked for deletion */
+ if (lpService->bDeleted)
+ return ERROR_SERVICE_MARKED_FOR_DELETE;
+ /* Return Error exist */
+ return ERROR_SERVICE_EXISTS;
+ }
+
+ if (lpDisplayName != NULL &&
+ ScmGetServiceEntryByDisplayName(lpDisplayName) != NULL)
+ return ERROR_DUPLICATE_SERVICE_NAME;
+
+ if (dwServiceType & SERVICE_DRIVER)
+ {
+ dwError = ScmCanonDriverImagePath(dwStartType,
+ lpBinaryPathName,
+ &lpImagePath);
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+ }
+ else
+ {
+ if (dwStartType == SERVICE_BOOT_START ||
+ dwStartType == SERVICE_SYSTEM_START)
+ {
+ return ERROR_INVALID_PARAMETER;
+ }
+ }
+
+ /* Allocate a new service entry */
+ dwError = ScmCreateNewServiceRecord(lpServiceName,
+ &lpService);
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+
+ /* Fill the new service entry */
+ lpService->Status.dwServiceType = dwServiceType;
+ lpService->dwStartType = dwStartType;
+ lpService->dwErrorControl = dwErrorControl;
+
+ /* Fill the display name */
+ if (lpDisplayName != NULL &&
+ *lpDisplayName != 0 &&
+ _wcsicmp(lpService->lpDisplayName, lpDisplayName) != 0)
+ {
+ lpService->lpDisplayName = (WCHAR*) HeapAlloc(GetProcessHeap(), 0,
+ (wcslen(lpDisplayName) + 1) * sizeof(WCHAR));
+ if (lpService->lpDisplayName == NULL)
+ {
+ dwError = ERROR_NOT_ENOUGH_MEMORY;
+ goto done;
+ }
+ wcscpy(lpService->lpDisplayName, lpDisplayName);
+ }
+
+ /* Assign the service to a group */
+ if (lpLoadOrderGroup != NULL && *lpLoadOrderGroup != 0)
+ {
+ dwError = ScmSetServiceGroup(lpService,
+ lpLoadOrderGroup);
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+ }
+
+ /* Assign a new tag */
+ if (lpdwTagId != NULL)
+ {
+ dwError = ScmAssignNewTag(lpService);
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+ }
+
+ /* Write service data to the registry */
+ /* Create the service key */
+ dwError = ScmCreateServiceKey(lpServiceName,
+ KEY_WRITE,
+ &hServiceKey);
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+
+ /* Set the display name */
+ if (lpDisplayName != NULL && *lpDisplayName != 0)
+ {
+ RegSetValueExW(hServiceKey,
+ L"DisplayName",
+ 0,
+ REG_SZ,
+ (LPBYTE)lpDisplayName,
+ (wcslen(lpDisplayName) + 1) * sizeof(WCHAR));
+ }
+
+ /* Set the service type */
+ dwError = RegSetValueExW(hServiceKey,
+ L"Type",
+ 0,
+ REG_DWORD,
+ (LPBYTE)&dwServiceType,
+ sizeof(DWORD));
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+
+ /* Set the start value */
+ dwError = RegSetValueExW(hServiceKey,
+ L"Start",
+ 0,
+ REG_DWORD,
+ (LPBYTE)&dwStartType,
+ sizeof(DWORD));
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+
+ /* Set the error control value */
+ dwError = RegSetValueExW(hServiceKey,
+ L"ErrorControl",
+ 0,
+ REG_DWORD,
+ (LPBYTE)&dwErrorControl,
+ sizeof(DWORD));
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+
+ /* Set the image path */
+ if (dwServiceType & SERVICE_WIN32)
+ {
+ dwError = RegSetValueExW(hServiceKey,
+ L"ImagePath",
+ 0,
+ REG_EXPAND_SZ,
+ (LPBYTE)lpBinaryPathName,
+ (wcslen(lpBinaryPathName) + 1) * sizeof(WCHAR));
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+ }
+ else if (dwServiceType & SERVICE_DRIVER)
+ {
+ dwError = RegSetValueExW(hServiceKey,
+ L"ImagePath",
+ 0,
+ REG_EXPAND_SZ,
+ (LPBYTE)lpImagePath,
+ (wcslen(lpImagePath) + 1) * sizeof(WCHAR));
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+ }
+
+ /* Set the group name */
+ if (lpLoadOrderGroup != NULL && *lpLoadOrderGroup != 0)
+ {
+ dwError = RegSetValueExW(hServiceKey,
+ L"Group",
+ 0,
+ REG_SZ,
+ (LPBYTE)lpLoadOrderGroup,
+ (wcslen(lpLoadOrderGroup) + 1) * sizeof(WCHAR));
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+ }
+
+ if (lpdwTagId != NULL)
+ {
+ dwError = RegSetValueExW(hServiceKey,
+ L"Tag",
+ 0,
+ REG_DWORD,
+ (LPBYTE)&lpService->dwTag,
+ sizeof(DWORD));
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+ }
+
+ /* Write dependencies */
+ if (lpDependencies != NULL && *lpDependencies != 0)
+ {
+ dwError = ScmWriteDependencies(hServiceKey,
+ (LPWSTR)lpDependencies,
+ dwDependSize);
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+ }
+
+ /* Write service start name */
+ if (dwServiceType & SERVICE_WIN32)
+ {
+ lpObjectName = (lpServiceStartName != NULL) ? (LPWSTR)lpServiceStartName : L"LocalSystem";
+ dwError = RegSetValueExW(hServiceKey,
+ L"ObjectName",
+ 0,
+ REG_SZ,
+ (LPBYTE)lpObjectName,
+ (wcslen(lpObjectName) + 1) * sizeof(WCHAR));
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+ }
+
+ if (lpPassword != NULL)
+ {
+ /* FIXME: Write password */
+ }
+
+ dwError = ScmCreateServiceHandle(lpService,
+ &hServiceHandle);
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+
+ dwError = ScmCheckAccess(hServiceHandle,
+ dwDesiredAccess);
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+
+ lpService->dwRefCount = 1;
+ DPRINT("CreateService - lpService->dwRefCount %u\n", lpService->dwRefCount);
+
+done:;
+ if (hServiceKey != NULL)
+ RegCloseKey(hServiceKey);
+
+ if (dwError == ERROR_SUCCESS)
+ {
+ DPRINT("hService %p\n", hServiceHandle);
+ *lpServiceHandle = (SC_RPC_HANDLE)hServiceHandle;
+
+ if (lpdwTagId != NULL)
+ *lpdwTagId = lpService->dwTag;
+ }
+ else
+ {
+ /* Release the display name buffer */
+ if (lpService->lpServiceName != NULL)
+ HeapFree(GetProcessHeap(), 0, lpService->lpDisplayName);
+
+ if (hServiceHandle)
+ {
+ /* Remove the service handle */
+ HeapFree(GetProcessHeap(), 0, hServiceHandle);
+ }
+
+ if (lpService != NULL)
+ {
+ /* FIXME: remove the service entry */
+ }
+ }
+
+ if (lpImagePath != NULL)
+ HeapFree(GetProcessHeap(), 0, lpImagePath);
+
+ DPRINT("RCreateServiceW() done (Error %lu)\n", dwError);
+
+ return dwError;
+}
+
+
+/* Function 13 */
+DWORD REnumDependentServicesW(
+ SC_RPC_HANDLE hService,
+ DWORD dwServiceState,
+ LPBYTE lpServices,
+ DWORD cbBufSize,
+ LPBOUNDED_DWORD_256K pcbBytesNeeded,
+ LPBOUNDED_DWORD_256K lpServicesReturned)
+{
+ DWORD dwError = ERROR_SUCCESS;
+ DWORD dwServicesReturned = 0;
+ DWORD dwServiceCount;
+ HKEY hServicesKey = NULL;
+ PSERVICE_HANDLE hSvc;
+ PSERVICE lpService = NULL;
+ PSERVICE *lpServicesArray = NULL;
+ LPENUM_SERVICE_STATUSW lpServicesPtr = NULL;
+ LPWSTR lpStr;
+
+ *pcbBytesNeeded = 0;
+ *lpServicesReturned = 0;
+
+ DPRINT("REnumDependentServicesW() called\n");
+
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
+ {
+ DPRINT1("Invalid service handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ lpService = hSvc->ServiceEntry;
+
+ /* Check access rights */
+ if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
+ SC_MANAGER_ENUMERATE_SERVICE))
+ {
+ DPRINT("Insufficient access rights! 0x%lx\n",
+ hSvc->Handle.DesiredAccess);
+ return ERROR_ACCESS_DENIED;
+ }
+
+ /* Open the Services Reg key */
+ dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ L"System\\CurrentControlSet\\Services",
+ 0,
+ KEY_READ,
+ &hServicesKey);
+ if (dwError != ERROR_SUCCESS)
+ return dwError;
+
+ /* First determine the bytes needed and get the number of dependent services */
+ dwError = Int_EnumDependentServicesW(hServicesKey,
+ lpService,
+ dwServiceState,
+ NULL,
+ pcbBytesNeeded,
+ &dwServicesReturned);
+ if (dwError != ERROR_SUCCESS)
+ goto Done;
+
+ /* If buffer size is less than the bytes needed or pointer is null */
+ if ((!lpServices) || (cbBufSize < *pcbBytesNeeded))
+ {
+ dwError = ERROR_MORE_DATA;
+ goto Done;
+ }
+
+ /* Allocate memory for array of service pointers */
+ lpServicesArray = HeapAlloc(GetProcessHeap(),
+ 0,
+ (dwServicesReturned + 1) * sizeof(PSERVICE));
+ if (!lpServicesArray)
+ {
+ DPRINT("Could not allocate a buffer!!\n");
+ dwError = ERROR_NOT_ENOUGH_MEMORY;
+ goto Done;
+ }
+
+ dwServicesReturned = 0;
+ *pcbBytesNeeded = 0;
+
+ dwError = Int_EnumDependentServicesW(hServicesKey,
+ lpService,
+ dwServiceState,
+ lpServicesArray,
+ pcbBytesNeeded,
+ &dwServicesReturned);
+ if (dwError != ERROR_SUCCESS)
+ {
+ goto Done;
+ }
+
+ lpServicesPtr = (LPENUM_SERVICE_STATUSW) lpServices;
+ lpStr = (LPWSTR)(lpServices + (dwServicesReturned * sizeof(ENUM_SERVICE_STATUSW)));
+
+ /* Copy EnumDepenedentService to Buffer */
+ for (dwServiceCount = 0; dwServiceCount < dwServicesReturned; dwServiceCount++)
+ {
+ lpService = lpServicesArray[dwServiceCount];
+
+ /* Copy status info */
+ memcpy(&lpServicesPtr->ServiceStatus,
+ &lpService->Status,
+ sizeof(SERVICE_STATUS));
+
+ /* Copy display name */
+ wcscpy(lpStr, lpService->lpDisplayName);
+ lpServicesPtr->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServices);
+ lpStr += (wcslen(lpService->lpDisplayName) + 1);
+
+ /* Copy service name */
+ wcscpy(lpStr, lpService->lpServiceName);
+ lpServicesPtr->lpServiceName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServices);
+ lpStr += (wcslen(lpService->lpServiceName) + 1);
+
+ lpServicesPtr ++;
+ }
+
+ *lpServicesReturned = dwServicesReturned;
+
+Done:
+ if (lpServicesArray != NULL)
+ HeapFree(GetProcessHeap(), 0, lpServicesArray);
+
+ RegCloseKey(hServicesKey);
+
+ DPRINT("REnumDependentServicesW() done (Error %lu)\n", dwError);
+
+ return dwError;
+}
+
+
+/* Function 14 */
+DWORD REnumServicesStatusW(
+ SC_RPC_HANDLE hSCManager,
+ DWORD dwServiceType,
+ DWORD dwServiceState,
+ LPBYTE lpBuffer,
+ DWORD dwBufSize,
+ LPBOUNDED_DWORD_256K pcbBytesNeeded,
+ LPBOUNDED_DWORD_256K lpServicesReturned,
+ LPBOUNDED_DWORD_256K lpResumeHandle)
+{
+ PMANAGER_HANDLE hManager;
+ PSERVICE lpService;
+ DWORD dwError = ERROR_SUCCESS;
+ PLIST_ENTRY ServiceEntry;
+ PSERVICE CurrentService;
+ DWORD dwState;
+ DWORD dwRequiredSize;
+ DWORD dwServiceCount;
+ DWORD dwSize;
+ DWORD dwLastResumeCount = 0;
+ LPENUM_SERVICE_STATUSW lpStatusPtr;
+ LPWSTR lpStringPtr;
+
+ DPRINT("REnumServicesStatusW() called\n");
+
+ if (ScmShutdown)
+ return ERROR_SHUTDOWN_IN_PROGRESS;
+
+ hManager = ScmGetServiceManagerFromHandle(hSCManager);
+ if (hManager == NULL)
+ {
+ DPRINT1("Invalid service manager handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+
+ *pcbBytesNeeded = 0;
+ *lpServicesReturned = 0;
+
+ if ((dwServiceType!=SERVICE_DRIVER) && (dwServiceType!=SERVICE_WIN32))
+ {
+ DPRINT("Not a valid Service Type!\n");
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ if ((dwServiceState<SERVICE_ACTIVE) || (dwServiceState>SERVICE_STATE_ALL))
+ {
+ DPRINT("Not a valid Service State!\n");
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ /* Check access rights */
+ if (!RtlAreAllAccessesGranted(hManager->Handle.DesiredAccess,
+ SC_MANAGER_ENUMERATE_SERVICE))
+ {
+ DPRINT("Insufficient access rights! 0x%lx\n",
+ hManager->Handle.DesiredAccess);
+ return ERROR_ACCESS_DENIED;
+ }
+
+ if (lpResumeHandle)
+ dwLastResumeCount = *lpResumeHandle;
+
+ /* FIXME: Lock the service list shared */
+
+ lpService = ScmGetServiceEntryByResumeCount(dwLastResumeCount);
+ if (lpService == NULL)
+ {
+ dwError = ERROR_SUCCESS;
+ goto Done;
+ }
+
+ dwRequiredSize = 0;
+ dwServiceCount = 0;
+
+ for (ServiceEntry = &lpService->ServiceListEntry;
+ ServiceEntry != &ServiceListHead;
+ ServiceEntry = ServiceEntry->Flink)
+ {
+ CurrentService = CONTAINING_RECORD(ServiceEntry,
+ SERVICE,
+ ServiceListEntry);
+
+ if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
+ continue;
+
+ dwState = SERVICE_ACTIVE;
+ if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
+ dwState = SERVICE_INACTIVE;
+
+ if ((dwState & dwServiceState) == 0)
+ continue;
+
+ dwSize = sizeof(ENUM_SERVICE_STATUSW) +
+ ((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
+ ((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
+
+ if (dwRequiredSize + dwSize > dwBufSize)
+ {
+ DPRINT("Service name: %S no fit\n", CurrentService->lpServiceName);
+ break;
+ }
+
+ DPRINT("Service name: %S fit\n", CurrentService->lpServiceName);
+ dwRequiredSize += dwSize;
+ dwServiceCount++;
+ dwLastResumeCount = CurrentService->dwResumeCount;
+ }
+
+ DPRINT("dwRequiredSize: %lu\n", dwRequiredSize);
+ DPRINT("dwServiceCount: %lu\n", dwServiceCount);
+
+ for (;
+ ServiceEntry != &ServiceListHead;
+ ServiceEntry = ServiceEntry->Flink)
+ {
+ CurrentService = CONTAINING_RECORD(ServiceEntry,
+ SERVICE,
+ ServiceListEntry);
+
+ if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
+ continue;
+
+ dwState = SERVICE_ACTIVE;
+ if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
+ dwState = SERVICE_INACTIVE;
+
+ if ((dwState & dwServiceState) == 0)
+ continue;
+
+ dwRequiredSize += (sizeof(ENUM_SERVICE_STATUSW) +
+ ((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
+ ((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR)));
+
+ dwError = ERROR_MORE_DATA;
+ }
+
+ DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize);
+
+ if (lpResumeHandle)
+ *lpResumeHandle = dwLastResumeCount;
+
+ *lpServicesReturned = dwServiceCount;
+ *pcbBytesNeeded = dwRequiredSize;
+
+ lpStatusPtr = (LPENUM_SERVICE_STATUSW)lpBuffer;
+ lpStringPtr = (LPWSTR)((ULONG_PTR)lpBuffer +
+ dwServiceCount * sizeof(ENUM_SERVICE_STATUSW));
+
+ dwRequiredSize = 0;
+ for (ServiceEntry = &lpService->ServiceListEntry;
+ ServiceEntry != &ServiceListHead;
+ ServiceEntry = ServiceEntry->Flink)
+ {
+ CurrentService = CONTAINING_RECORD(ServiceEntry,
+ SERVICE,
+ ServiceListEntry);
+
+ if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
+ continue;
+
+ dwState = SERVICE_ACTIVE;
+ if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
+ dwState = SERVICE_INACTIVE;
+
+ if ((dwState & dwServiceState) == 0)
+ continue;
+
+ dwSize = sizeof(ENUM_SERVICE_STATUSW) +
+ ((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
+ ((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
+
+ if (dwRequiredSize + dwSize > dwBufSize)
+ break;
+
+ /* Copy the service name */
+ wcscpy(lpStringPtr, CurrentService->lpServiceName);
+ lpStatusPtr->lpServiceName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpBuffer);
+ lpStringPtr += (wcslen(CurrentService->lpServiceName) + 1);
+
+ /* Copy the display name */
+ wcscpy(lpStringPtr, CurrentService->lpDisplayName);
+ lpStatusPtr->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpBuffer);
+ lpStringPtr += (wcslen(CurrentService->lpDisplayName) + 1);
+
+ /* Copy the status information */
+ memcpy(&lpStatusPtr->ServiceStatus,
+ &CurrentService->Status,
+ sizeof(SERVICE_STATUS));
+
+ lpStatusPtr++;
+ dwRequiredSize += dwSize;
+ }
+
+ if (dwError == 0)
+ {
+ *pcbBytesNeeded = 0;
+ if (lpResumeHandle) *lpResumeHandle = 0;
+ }
+
+Done:;
+ /* FIXME: Unlock the service list */
+
+ DPRINT("REnumServicesStatusW() done (Error %lu)\n", dwError);
+
+ return dwError;
+}
+
+
+/* Function 15 */
+DWORD ROpenSCManagerW(
+ LPWSTR lpMachineName,
+ LPWSTR lpDatabaseName,
+ DWORD dwDesiredAccess,
+ LPSC_RPC_HANDLE lpScHandle)
+{
+ DWORD dwError;
+ SC_HANDLE hHandle;
+
+ DPRINT("ROpenSCManagerW() called\n");
+ DPRINT("lpMachineName = %p\n", lpMachineName);
+ DPRINT("lpMachineName: %S\n", lpMachineName);
+ DPRINT("lpDataBaseName = %p\n", lpDatabaseName);
+ DPRINT("lpDataBaseName: %S\n", lpDatabaseName);
+ DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess);
+
+ if (ScmShutdown)
+ return ERROR_SHUTDOWN_IN_PROGRESS;
+
+ if (!lpScHandle)
+ return ERROR_INVALID_PARAMETER;
+
+ dwError = ScmCreateManagerHandle(lpDatabaseName,
+ &hHandle);
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT("ScmCreateManagerHandle() failed (Error %lu)\n", dwError);
+ return dwError;
+ }
+
+ /* Check the desired access */
+ dwError = ScmCheckAccess(hHandle,
+ dwDesiredAccess | SC_MANAGER_CONNECT);
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT("ScmCheckAccess() failed (Error %lu)\n", dwError);
+ HeapFree(GetProcessHeap(), 0, hHandle);
+ return dwError;
+ }
+
+ *lpScHandle = (SC_RPC_HANDLE)hHandle;
+ DPRINT("*hScm = %p\n", *lpScHandle);
+
+ DPRINT("ROpenSCManagerW() done\n");
+
+ return ERROR_SUCCESS;
+}
+
+
+/* Function 16 */
+DWORD ROpenServiceW(
+ SC_RPC_HANDLE hSCManager,
+ LPWSTR lpServiceName,
+ DWORD dwDesiredAccess,
+ LPSC_RPC_HANDLE lpServiceHandle)
+{
+ PSERVICE lpService;
+ PMANAGER_HANDLE hManager;
+ SC_HANDLE hHandle;
+ DWORD dwError;
+
+ DPRINT("ROpenServiceW() called\n");
+ DPRINT("hSCManager = %p\n", hSCManager);
+ DPRINT("lpServiceName = %p\n", lpServiceName);
+ DPRINT("lpServiceName: %S\n", lpServiceName);
+ DPRINT("dwDesiredAccess = %x\n", dwDesiredAccess);
+
+ if (ScmShutdown)
+ return ERROR_SHUTDOWN_IN_PROGRESS;
+
+ hManager = ScmGetServiceManagerFromHandle(hSCManager);
+ if (hManager == NULL)
+ {
+ DPRINT1("Invalid service manager handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ if (!lpServiceHandle)
+ return ERROR_INVALID_PARAMETER;
+
+ if (!lpServiceName)
+ return ERROR_INVALID_ADDRESS;
+
+ /* FIXME: Lock the service list */
+
+ /* Get service database entry */
+ lpService = ScmGetServiceEntryByName(lpServiceName);
+ if (lpService == NULL)
+ {
+ DPRINT("Could not find a service!\n");
+ return ERROR_SERVICE_DOES_NOT_EXIST;
+ }
+
+ /* Create a service handle */
+ dwError = ScmCreateServiceHandle(lpService,
+ &hHandle);
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT("ScmCreateServiceHandle() failed (Error %lu)\n", dwError);
+ return dwError;
+ }
+
+ /* Check the desired access */
+ dwError = ScmCheckAccess(hHandle,
+ dwDesiredAccess);
+ if (dwError != ERROR_SUCCESS)
+ {
+ DPRINT("ScmCheckAccess() failed (Error %lu)\n", dwError);
+ HeapFree(GetProcessHeap(), 0, hHandle);
+ return dwError;
+ }
+
+ lpService->dwRefCount++;
+ DPRINT("OpenService - lpService->dwRefCount %u\n",lpService->dwRefCount);
+
+ *lpServiceHandle = (SC_RPC_HANDLE)hHandle;
+ DPRINT("*hService = %p\n", *lpServiceHandle);
+
+ DPRINT("ROpenServiceW() done\n");
+
+ return ERROR_SUCCESS;
+}
+
+
+/* Function 17 */
+DWORD RQueryServiceConfigW(
+ SC_RPC_HANDLE hService,
+ LPQUERY_SERVICE_CONFIGW lpServiceConfig,
+ DWORD cbBufSize,
+ LPBOUNDED_DWORD_8K pcbBytesNeeded)
+{
+ DWORD dwError = ERROR_SUCCESS;
+ PSERVICE_HANDLE hSvc;
+ PSERVICE lpService = NULL;
+ HKEY hServiceKey = NULL;
+ LPWSTR lpImagePath = NULL;
+ LPWSTR lpServiceStartName = NULL;
+ LPWSTR lpDependencies = NULL;
+ DWORD dwDependenciesLength = 0;
+ DWORD dwRequiredSize;
+ LPQUERY_SERVICE_CONFIGW lpConfig = NULL;
+ WCHAR lpEmptyString[] = {0,0};
+ LPWSTR lpStr;
+
+ DPRINT("RQueryServiceConfigW() called\n");
+
+ if (ScmShutdown)
+ return ERROR_SHUTDOWN_IN_PROGRESS;
+
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
+ {
+ DPRINT1("Invalid service handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
+ SERVICE_QUERY_CONFIG))
+ {
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ return ERROR_ACCESS_DENIED;
+ }
+
+ lpService = hSvc->ServiceEntry;
+ if (lpService == NULL)
+ {
+ DPRINT("lpService == NULL!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ /* FIXME: Lock the service database shared */
+
+ dwError = ScmOpenServiceKey(lpService->lpServiceName,
+ KEY_READ,
+ &hServiceKey);
+ if (dwError != ERROR_SUCCESS)
+ goto Done;
+
+ /* Read the image path */
+ dwError = ScmReadString(hServiceKey,
+ L"ImagePath",
+ &lpImagePath);
+ if (dwError != ERROR_SUCCESS)
+ goto Done;
+
+ /* Read the service start name */
+ ScmReadString(hServiceKey,
+ L"ObjectName",
+ &lpServiceStartName);
+
+ /* Read the dependencies */
+ ScmReadDependencies(hServiceKey,
+ &lpDependencies,
+ &dwDependenciesLength);
+
+ dwRequiredSize = sizeof(QUERY_SERVICE_CONFIGW);
+
+ if (lpImagePath != NULL)
+ dwRequiredSize += ((wcslen(lpImagePath) + 1) * sizeof(WCHAR));
+ else
+ dwRequiredSize += 2 * sizeof(WCHAR);
+
+ if (lpService->lpGroup != NULL)
+ dwRequiredSize += ((wcslen(lpService->lpGroup->lpGroupName) + 1) * sizeof(WCHAR));
+ else
+ dwRequiredSize += 2 * sizeof(WCHAR);
+
+ if (lpDependencies != NULL)
+ dwRequiredSize += dwDependenciesLength * sizeof(WCHAR);
+ else
+ dwRequiredSize += 2 * sizeof(WCHAR);
+
+ if (lpServiceStartName != NULL)
+ dwRequiredSize += ((wcslen(lpServiceStartName) + 1) * sizeof(WCHAR));
+ else
+ dwRequiredSize += 2 * sizeof(WCHAR);
+
+ if (lpService->lpDisplayName != NULL)
+ dwRequiredSize += ((wcslen(lpService->lpDisplayName) + 1) * sizeof(WCHAR));
+ else
+ dwRequiredSize += 2 * sizeof(WCHAR);
+
+ if (lpServiceConfig == NULL || cbBufSize < dwRequiredSize)
+ {
+ dwError = ERROR_INSUFFICIENT_BUFFER;
+ }
+ else
+ {
+ lpConfig = (LPQUERY_SERVICE_CONFIGW)lpServiceConfig;
+ lpConfig->dwServiceType = lpService->Status.dwServiceType;
+ lpConfig->dwStartType = lpService->dwStartType;
+ lpConfig->dwErrorControl = lpService->dwErrorControl;
+ lpConfig->dwTagId = lpService->dwTag;
+
+ lpStr = (LPWSTR)(lpConfig + 1);
+
+ /* Append the image path */
+ if (lpImagePath != NULL)
+ {
+ wcscpy(lpStr, lpImagePath);
+ }
+ else
+ {
+ wcscpy(lpStr, lpEmptyString);
+ }
+
+ lpConfig->lpBinaryPathName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
+ lpStr += (wcslen(lpStr) + 1);
+
+ /* Append the group name */
+ if (lpService->lpGroup != NULL)
+ {
+ wcscpy(lpStr, lpService->lpGroup->lpGroupName);
+ }
+ else
+ {
+ wcscpy(lpStr, lpEmptyString);
+ }
+
+ lpConfig->lpLoadOrderGroup = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
+ lpStr += (wcslen(lpStr) + 1);
+
+ /* Append Dependencies */
+ if (lpDependencies != NULL)
+ {
+ memcpy(lpStr,
+ lpDependencies,
+ dwDependenciesLength * sizeof(WCHAR));
+ }
+ else
+ {
+ wcscpy(lpStr, lpEmptyString);
+ }
+
+ lpConfig->lpDependencies = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
+ if (lpDependencies != NULL)
+ lpStr += dwDependenciesLength * sizeof(WCHAR);
+ else
+ lpStr += (wcslen(lpStr) + 1);
+
+ /* Append the service start name */
+ if (lpServiceStartName != NULL)
+ {
+ wcscpy(lpStr, lpServiceStartName);
+ }
+ else
+ {
+ wcscpy(lpStr, lpEmptyString);
+ }
+
+ lpConfig->lpServiceStartName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
+ lpStr += (wcslen(lpStr) + 1);
+
+ /* Append the display name */
+ if (lpService->lpDisplayName != NULL)
+ {
+ wcscpy(lpStr, lpService->lpDisplayName);
+ }
+ else
+ {
+ wcscpy(lpStr, lpEmptyString);
+ }
+
+ lpConfig->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
+ }
+
+ if (pcbBytesNeeded != NULL)
+ *pcbBytesNeeded = dwRequiredSize;
+
+Done:;
+ if (lpImagePath != NULL)
+ HeapFree(GetProcessHeap(), 0, lpImagePath);
+
+ if (lpServiceStartName != NULL)
+ HeapFree(GetProcessHeap(), 0, lpServiceStartName);
+
+ if (lpDependencies != NULL)
+ HeapFree(GetProcessHeap(), 0, lpDependencies);
+
+ if (hServiceKey != NULL)
+ RegCloseKey(hServiceKey);
+
+ /* FIXME: Unlock the service database */
+
+ DPRINT("RQueryServiceConfigW() done\n");
+
+ return dwError;
+}
+
+
+/* Function 18 */
+DWORD RQueryServiceLockStatusW(
+ SC_RPC_HANDLE hSCManager,
+ LPQUERY_SERVICE_LOCK_STATUSW lpLockStatus,
+ DWORD cbBufSize,
+ LPBOUNDED_DWORD_4K pcbBytesNeeded)
+{
+ UNIMPLEMENTED;
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 19 */
+DWORD RStartServiceW(
+ SC_RPC_HANDLE hService,
+ DWORD argc,
+ LPSTRING_PTRSW argv)
+{
+ DWORD dwError = ERROR_SUCCESS;
+ PSERVICE_HANDLE hSvc;
+ PSERVICE lpService = NULL;
+
+ DPRINT("RStartServiceW() called\n");
+
+ if (ScmShutdown)
+ return ERROR_SHUTDOWN_IN_PROGRESS;
+
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
+ {
+ DPRINT1("Invalid service handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
+ SERVICE_START))
+ {
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ return ERROR_ACCESS_DENIED;
+ }
+
+ lpService = hSvc->ServiceEntry;
+ if (lpService == NULL)
+ {
+ DPRINT("lpService == NULL!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ if (lpService->dwStartType == SERVICE_DISABLED)
+ return ERROR_SERVICE_DISABLED;
+
+ if (lpService->bDeleted)
+ return ERROR_SERVICE_MARKED_FOR_DELETE;
+
+ if (argv) {
+ UNIMPLEMENTED;
+ argv = NULL;
+ }
+
+ /* Start the service */
+ dwError = ScmStartService(lpService, argc, (LPWSTR *)argv);
+
+ return dwError;
+}
+
+
+/* Function 20 */
+DWORD RGetServiceDisplayNameW(
+ SC_RPC_HANDLE hSCManager,
+ LPCWSTR lpServiceName,
+ LPWSTR lpDisplayName,
+ DWORD *lpcchBuffer)
+{
+// PMANAGER_HANDLE hManager;
+ PSERVICE lpService;
+ DWORD dwLength;
+ DWORD dwError;
+
+ DPRINT("RGetServiceDisplayNameW() called\n");
+ DPRINT("hSCManager = %p\n", hSCManager);
+ DPRINT("lpServiceName: %S\n", lpServiceName);
+ DPRINT("lpDisplayName: %p\n", lpDisplayName);
+ DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer);
+
+// hManager = (PMANAGER_HANDLE)hSCManager;
+// if (hManager->Handle.Tag != MANAGER_TAG)
+// {
+// DPRINT("Invalid manager handle!\n");
+// return ERROR_INVALID_HANDLE;
+// }
+
+ /* Get service database entry */
+ lpService = ScmGetServiceEntryByName(lpServiceName);
+ if (lpService == NULL)
+ {
+ DPRINT("Could not find a service!\n");
+
+ /* If the service could not be found and lpcchBuffer is less than 2, windows
+ puts null in lpDisplayName and puts 2 in lpcchBuffer */
+ if (*lpcchBuffer < 2)
+ {
+ *lpcchBuffer = 2;
+ if (lpDisplayName != NULL)
+ {
+ *lpDisplayName = '\0';
+ }
+ }
+
+ return ERROR_SERVICE_DOES_NOT_EXIST;
+ }
+
+ if (!lpService->lpDisplayName)
+ {
+ dwLength = wcslen(lpService->lpServiceName);
+
+ if (lpDisplayName != NULL &&
+ *lpcchBuffer > dwLength)
+ {
+ wcscpy(lpDisplayName, lpService->lpServiceName);
+ }
+ }
+ else
+ {
+ dwLength = wcslen(lpService->lpDisplayName);
+
+ if (lpDisplayName != NULL &&
+ *lpcchBuffer > dwLength)
+ {
+ wcscpy(lpDisplayName, lpService->lpDisplayName);
+ }
+ }
+
+ dwError = (*lpcchBuffer > dwLength) ? ERROR_SUCCESS : ERROR_INSUFFICIENT_BUFFER;
+
+ *lpcchBuffer = dwLength;
+
+ return dwError;
+}
+
+
+/* Function 21 */
+DWORD RGetServiceKeyNameW(
+ SC_RPC_HANDLE hSCManager,
+ LPCWSTR lpDisplayName,
+ LPWSTR lpServiceName,
+ DWORD *lpcchBuffer)
+{
+// PMANAGER_HANDLE hManager;
+ PSERVICE lpService;
+ DWORD dwLength;
+ DWORD dwError;
+
+ DPRINT("RGetServiceKeyNameW() called\n");
+ DPRINT("hSCManager = %p\n", hSCManager);
+ DPRINT("lpDisplayName: %S\n", lpDisplayName);
+ DPRINT("lpServiceName: %p\n", lpServiceName);
+ DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer);
+
+// hManager = (PMANAGER_HANDLE)hSCManager;
+// if (hManager->Handle.Tag != MANAGER_TAG)
+// {
+// DPRINT("Invalid manager handle!\n");
+// return ERROR_INVALID_HANDLE;
+// }
+
+ /* Get service database entry */
+ lpService = ScmGetServiceEntryByDisplayName(lpDisplayName);
+ if (lpService == NULL)
+ {
+ DPRINT("Could not find a service!\n");
+
+ /* If the service could not be found and lpcchBuffer is less than 2, windows
+ puts null in lpDisplayName and puts 2 in lpcchBuffer */
+ if (*lpcchBuffer < 2)
+ {
+ *lpcchBuffer = 2;
+ if (lpServiceName != NULL)
+ {
+ *lpServiceName = '\0';
+ }
+ }
+
+ return ERROR_SERVICE_DOES_NOT_EXIST;
+ }
+
+ dwLength = wcslen(lpService->lpServiceName);
+
+ if (lpServiceName != NULL &&
+ *lpcchBuffer > dwLength)
+ {
+ wcscpy(lpServiceName, lpService->lpServiceName);
+ *lpcchBuffer = dwLength;
+ return ERROR_SUCCESS;
+ }
+
+ dwError = (*lpcchBuffer > dwLength) ? ERROR_SUCCESS : ERROR_INSUFFICIENT_BUFFER;
+
+ *lpcchBuffer = dwLength;
+
+ return dwError;
+}
+
+
+/* Function 22 */
+DWORD RI_ScSetServiceBitsA(
+ RPC_SERVICE_STATUS_HANDLE hServiceStatus,
+ DWORD dwServiceBits,
+ int bSetBitsOn,
+ int bUpdateImmediately,
+ char *lpString)
+{
+ UNIMPLEMENTED;
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 23 */
+DWORD RChangeServiceConfigA(
+ SC_RPC_HANDLE hService,
+ DWORD dwServiceType,
+ DWORD dwStartType,
+ DWORD dwErrorControl,
+ LPSTR lpBinaryPathName,
+ LPSTR lpLoadOrderGroup,
+ LPDWORD lpdwTagId,
+ LPSTR lpDependencies,
+ DWORD dwDependSize,
+ LPSTR lpServiceStartName,
+ LPBYTE lpPassword,
+ DWORD dwPwSize,
+ LPSTR lpDisplayName)
+{
+ DWORD dwError = ERROR_SUCCESS;
+ PSERVICE_HANDLE hSvc;
+ PSERVICE lpService = NULL;
+ HKEY hServiceKey = NULL;
+ LPWSTR lpDisplayNameW = NULL;
+ // LPWSTR lpBinaryPathNameW = NULL;
+ LPWSTR lpLoadOrderGroupW = NULL;
+ LPWSTR lpDependenciesW = NULL;
+ // LPWSTR lpPasswordW = NULL;
+
+ DPRINT("RChangeServiceConfigA() called\n");
+ DPRINT("dwServiceType = %lu\n", dwServiceType);
+ DPRINT("dwStartType = %lu\n", dwStartType);
+ DPRINT("dwErrorControl = %lu\n", dwErrorControl);
+ DPRINT("lpBinaryPathName = %s\n", lpBinaryPathName);
+ DPRINT("lpLoadOrderGroup = %s\n", lpLoadOrderGroup);
+ DPRINT("lpDisplayName = %s\n", lpDisplayName);
+
+ if (ScmShutdown)
+ return ERROR_SHUTDOWN_IN_PROGRESS;
+
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
+ {
+ DPRINT1("Invalid service handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
+ SERVICE_CHANGE_CONFIG))
+ {
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ return ERROR_ACCESS_DENIED;
+ }
+
+ lpService = hSvc->ServiceEntry;
+ if (lpService == NULL)
+ {
+ DPRINT("lpService == NULL!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ /* FIXME: Lock database exclusively */
+
+ if (lpService->bDeleted)
+ {
+ /* FIXME: Unlock database */
+ DPRINT("The service has already been marked for delete!\n");
+ return ERROR_SERVICE_MARKED_FOR_DELETE;
+ }
+
+ /* Open the service key */
+ dwError = ScmOpenServiceKey(lpService->szServiceName,
+ KEY_SET_VALUE,
+ &hServiceKey);
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+
+ /* Write service data to the registry */
+
+ if (lpDisplayName != NULL && *lpDisplayName != 0)
+ {
+ /* Set the display name */
+ lpDisplayNameW = HeapAlloc(GetProcessHeap(),
+ 0,
+ (strlen(lpDisplayName) + 1) * sizeof(WCHAR));
+ if (lpDisplayNameW == NULL)
+ {
+ dwError = ERROR_NOT_ENOUGH_MEMORY;
+ goto done;
+ }
+
+ MultiByteToWideChar(CP_ACP,
+ 0,
+ lpDisplayName,
+ -1,
+ lpDisplayNameW,
+ strlen(lpDisplayName) + 1);
+
+ RegSetValueExW(hServiceKey,
+ L"DisplayName",
+ 0,
+ REG_SZ,
+ (LPBYTE)lpDisplayNameW,
+ (wcslen(lpDisplayNameW) + 1) * sizeof(WCHAR));
+
+ /* Update lpService->lpDisplayName */
+ if (lpService->lpDisplayName)
+ HeapFree(GetProcessHeap(), 0, lpService->lpDisplayName);
+
+ lpService->lpDisplayName = lpDisplayNameW;
+ }
+
+ if (dwServiceType != SERVICE_NO_CHANGE)
+ {
+ /* Set the service type */
+ dwError = RegSetValueExW(hServiceKey,
+ L"Type",
+ 0,
+ REG_DWORD,
+ (LPBYTE)&dwServiceType,
+ sizeof(DWORD));
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+
+ lpService->Status.dwServiceType = dwServiceType;
+ }
+
+ if (dwStartType != SERVICE_NO_CHANGE)
+ {
+ /* Set the start value */
+ dwError = RegSetValueExW(hServiceKey,
+ L"Start",
+ 0,
+ REG_DWORD,
+ (LPBYTE)&dwStartType,
+ sizeof(DWORD));
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+
+ lpService->dwStartType = dwStartType;
+ }
+
+ if (dwErrorControl != SERVICE_NO_CHANGE)
+ {
+ /* Set the error control value */
+ dwError = RegSetValueExW(hServiceKey,
+ L"ErrorControl",
+ 0,
+ REG_DWORD,
+ (LPBYTE)&dwErrorControl,
+ sizeof(DWORD));
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+
+ lpService->dwErrorControl = dwErrorControl;
+ }
+
+#if 0
+ /* FIXME: set the new ImagePath value */
+
+ /* Set the image path */
+ if (dwServiceType & SERVICE_WIN32)
+ {
+ if (lpBinaryPathName != NULL && *lpBinaryPathName != 0)
+ {
+ lpBinaryPathNameW=HeapAlloc(GetProcessHeap(),0, (strlen(lpBinaryPathName)+1) * sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, lpBinaryPathNameW, strlen(lpBinaryPathName)+1);
+ dwError = RegSetValueExW(hServiceKey,
+ L"ImagePath",
+ 0,
+ REG_EXPAND_SZ,
+ (LPBYTE)lpBinaryPathNameW,
+ (wcslen(lpBinaryPathNameW) + 1) * sizeof(WCHAR));
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+ }
+ }
+ else if (dwServiceType & SERVICE_DRIVER)
+ {
+ if (lpImagePath != NULL && *lpImagePath != 0)
+ {
+ dwError = RegSetValueExW(hServiceKey,
+ L"ImagePath",
+ 0,
+ REG_EXPAND_SZ,
+ (LPBYTE)lpImagePath,
+ (wcslen(lpImagePath) + 1) *sizeof(WCHAR));
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+ }
+ }
+#endif
+
+ /* Set the group name */
+ if (lpLoadOrderGroup != NULL && *lpLoadOrderGroup != 0)
+ {
+ lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(),
+ 0,
+ (strlen(lpLoadOrderGroup) + 1) * sizeof(WCHAR));
+ if (lpLoadOrderGroupW == NULL)
+ {
+ dwError = ERROR_NOT_ENOUGH_MEMORY;
+ goto done;
+ }
+
+ MultiByteToWideChar(CP_ACP,
+ 0,
+ lpLoadOrderGroup,
+ -1,
+ lpLoadOrderGroupW,
+ strlen(lpLoadOrderGroup) + 1);
+
+ dwError = RegSetValueExW(hServiceKey,
+ L"Group",
+ 0,
+ REG_SZ,
+ (LPBYTE)lpLoadOrderGroupW,
+ (wcslen(lpLoadOrderGroupW) + 1) * sizeof(WCHAR));
+ if (dwError != ERROR_SUCCESS)
+ {
+ HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
+ goto done;
+ }
+
+ dwError = ScmSetServiceGroup(lpService,
+ lpLoadOrderGroupW);
+
+ HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
+
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+ }
+
+ if (lpdwTagId != NULL)
+ {
+ dwError = ScmAssignNewTag(lpService);
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+
+ dwError = RegSetValueExW(hServiceKey,
+ L"Tag",
+ 0,
+ REG_DWORD,
+ (LPBYTE)&lpService->dwTag,
+ sizeof(DWORD));
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+
+ *lpdwTagId = lpService->dwTag;
+ }
+
+ /* Write dependencies */
+ if (lpDependencies != NULL && *lpDependencies != 0)
+ {
+ lpDependenciesW = HeapAlloc(GetProcessHeap(),
+ 0,
+ (strlen(lpDependencies) + 1) * sizeof(WCHAR));
+ if (lpDependenciesW == NULL)
+ {
+ dwError = ERROR_NOT_ENOUGH_MEMORY;
+ goto done;
+ }
+
+ MultiByteToWideChar(CP_ACP,
+ 0,
+ lpDependencies,
+ dwDependSize,
+ lpDependenciesW,
+ strlen(lpDependencies) + 1);
+
+ dwError = ScmWriteDependencies(hServiceKey,
+ (LPWSTR)lpDependenciesW,
+ dwDependSize);
+
+ HeapFree(GetProcessHeap(), 0, lpDependenciesW);
+ }
+
+ if (lpPassword != NULL)
+ {
+ /* FIXME: Write password */
+ }
+
+ /* FIXME: Unlock database */
+
+done:
+ if (hServiceKey != NULL)
+ RegCloseKey(hServiceKey);
+
+ DPRINT("RChangeServiceConfigA() done (Error %lu)\n", dwError);
+
+ return dwError;
+}
+
+
+/* Function 24 */
+DWORD RCreateServiceA(
+ SC_RPC_HANDLE hSCManager,
+ LPSTR lpServiceName,
+ LPSTR lpDisplayName,
+ DWORD dwDesiredAccess,
+ DWORD dwServiceType,
+ DWORD dwStartType,
+ DWORD dwErrorControl,
+ LPSTR lpBinaryPathName,
+ LPSTR lpLoadOrderGroup,
+ LPDWORD lpdwTagId,
+ LPBYTE lpDependencies,
+ DWORD dwDependSize,
+ LPSTR lpServiceStartName,
+ LPBYTE lpPassword,
+ DWORD dwPwSize,
+ LPSC_RPC_HANDLE lpServiceHandle)
+{
+ DWORD dwError = ERROR_SUCCESS;
+ LPWSTR lpServiceNameW = NULL;
+ LPWSTR lpDisplayNameW = NULL;
+ LPWSTR lpBinaryPathNameW = NULL;
+ LPWSTR lpLoadOrderGroupW = NULL;
+ LPWSTR lpDependenciesW = NULL;
+ LPWSTR lpServiceStartNameW = NULL;
+ DWORD dwDependenciesLength = 0;
+ DWORD dwLength;
+ int len;
+ LPSTR lpStr;
+
+ if (lpServiceName)
+ {
+ len = MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, NULL, 0);
+ lpServiceNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!lpServiceNameW)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto cleanup;
+ }
+ MultiByteToWideChar(CP_ACP, 0, lpServiceName, -1, lpServiceNameW, len);
+ }
+
+ if (lpDisplayName)
+ {
+ len = MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, NULL, 0);
+ lpDisplayNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!lpDisplayNameW)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto cleanup;
+ }
+ MultiByteToWideChar(CP_ACP, 0, lpDisplayName, -1, lpDisplayNameW, len);
+ }
+
+ if (lpBinaryPathName)
+ {
+ len = MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, NULL, 0);
+ lpBinaryPathNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!lpBinaryPathNameW)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto cleanup;
+ }
+ MultiByteToWideChar(CP_ACP, 0, lpBinaryPathName, -1, lpBinaryPathNameW, len);
+ }
+
+ if (lpLoadOrderGroup)
+ {
+ len = MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, NULL, 0);
+ lpLoadOrderGroupW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!lpLoadOrderGroupW)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto cleanup;
+ }
+ MultiByteToWideChar(CP_ACP, 0, lpLoadOrderGroup, -1, lpLoadOrderGroupW, len);
+ }
+
+ if (lpDependencies)
+ {
+ lpStr = (LPSTR)lpDependencies;
+ while (*lpStr)
+ {
+ dwLength = strlen(lpStr) + 1;
+ dwDependenciesLength += dwLength;
+ lpStr = lpStr + dwLength;
+ }
+ dwDependenciesLength++;
+
+ lpDependenciesW = HeapAlloc(GetProcessHeap(), 0, dwDependenciesLength * sizeof(WCHAR));
+ if (!lpDependenciesW)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto cleanup;
+ }
+ MultiByteToWideChar(CP_ACP, 0, (LPSTR)lpDependencies, dwDependenciesLength, lpDependenciesW, dwDependenciesLength);
+ }
+
+ if (lpServiceStartName)
+ {
+ len = MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, NULL, 0);
+ lpServiceStartNameW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (!lpServiceStartNameW)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto cleanup;
+ }
+ MultiByteToWideChar(CP_ACP, 0, lpServiceStartName, -1, lpServiceStartNameW, len);
+ }
+
+ dwError = RCreateServiceW(hSCManager,
+ lpServiceNameW,
+ lpDisplayNameW,
+ dwDesiredAccess,
+ dwServiceType,
+ dwStartType,
+ dwErrorControl,
+ lpBinaryPathNameW,
+ lpLoadOrderGroupW,
+ lpdwTagId,
+ (LPBYTE)lpDependenciesW,
+ dwDependenciesLength,
+ lpServiceStartNameW,
+ lpPassword,
+ dwPwSize,
+ lpServiceHandle);
+
+cleanup:
+ if (lpServiceNameW !=NULL)
+ HeapFree(GetProcessHeap(), 0, lpServiceNameW);
+
+ if (lpDisplayNameW != NULL)
+ HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
+
+ if (lpBinaryPathNameW != NULL)
+ HeapFree(GetProcessHeap(), 0, lpBinaryPathNameW);
+
+ if (lpLoadOrderGroupW != NULL)
+ HeapFree(GetProcessHeap(), 0, lpLoadOrderGroupW);
+
+ if (lpDependenciesW != NULL)
+ HeapFree(GetProcessHeap(), 0, lpDependenciesW);
+
+ if (lpServiceStartNameW != NULL)
+ HeapFree(GetProcessHeap(), 0, lpServiceStartNameW);
+
+ return dwError;
+}
+
+
+/* Function 25 */
+DWORD REnumDependentServicesA(
+ SC_RPC_HANDLE hService,
+ DWORD dwServiceState,
+ LPBYTE lpServices,
+ DWORD cbBufSize,
+ LPBOUNDED_DWORD_256K pcbBytesNeeded,
+ LPBOUNDED_DWORD_256K lpServicesReturned)
+{
+ DWORD dwError = ERROR_SUCCESS;
+ DWORD dwServicesReturned = 0;
+ DWORD dwServiceCount;
+ HKEY hServicesKey = NULL;
+ PSERVICE_HANDLE hSvc;
+ PSERVICE lpService = NULL;
+ PSERVICE *lpServicesArray = NULL;
+ LPENUM_SERVICE_STATUSA lpServicesPtr = NULL;
+ LPSTR lpStr;
+
+ *pcbBytesNeeded = 0;
+ *lpServicesReturned = 0;
+
+ DPRINT("REnumDependentServicesA() called\n");
+
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
+ {
+ DPRINT1("Invalid service handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ lpService = hSvc->ServiceEntry;
+
+ /* Check access rights */
+ if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
+ SC_MANAGER_ENUMERATE_SERVICE))
+ {
+ DPRINT("Insufficient access rights! 0x%lx\n",
+ hSvc->Handle.DesiredAccess);
+ return ERROR_ACCESS_DENIED;
+ }
+
+ /* Open the Services Reg key */
+ dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
+ L"System\\CurrentControlSet\\Services",
+ 0,
+ KEY_READ,
+ &hServicesKey);
+
+ if (dwError != ERROR_SUCCESS)
+ return dwError;
+
+ /* NOTE: Windows calculates the pcbBytesNeeded based on WCHAR strings for
+ both EnumDependentServicesA and EnumDependentServicesW. So returned pcbBytesNeeded
+ are the same for both. Verified in WINXP. */
+
+ /* First determine the bytes needed and get the number of dependent services*/
+ dwError = Int_EnumDependentServicesW(hServicesKey,
+ lpService,
+ dwServiceState,
+ NULL,
+ pcbBytesNeeded,
+ &dwServicesReturned);
+ if (dwError != ERROR_SUCCESS)
+ goto Done;
+
+ /* If buffer size is less than the bytes needed or pointer is null*/
+ if ((!lpServices) || (cbBufSize < *pcbBytesNeeded))
+ {
+ dwError = ERROR_MORE_DATA;
+ goto Done;
+ }
+
+ /* Allocate memory for array of service pointers */
+ lpServicesArray = HeapAlloc(GetProcessHeap(),
+ 0,
+ (dwServicesReturned + 1) * sizeof(PSERVICE));
+ if (!lpServicesArray)
+ {
+ DPRINT("Could not allocate a buffer!!\n");
+ dwError = ERROR_NOT_ENOUGH_MEMORY;
+ goto Done;
+ }
+
+ dwServicesReturned = 0;
+ *pcbBytesNeeded = 0;
+
+ dwError = Int_EnumDependentServicesW(hServicesKey,
+ lpService,
+ dwServiceState,
+ lpServicesArray,
+ pcbBytesNeeded,
+ &dwServicesReturned);
+ if (dwError != ERROR_SUCCESS)
+ {
+ goto Done;
+ }
+
+ lpServicesPtr = (LPENUM_SERVICE_STATUSA)lpServices;
+ lpStr = (LPSTR)(lpServices + (dwServicesReturned * sizeof(ENUM_SERVICE_STATUSA)));
+
+ /* Copy EnumDepenedentService to Buffer */
+ for (dwServiceCount = 0; dwServiceCount < dwServicesReturned; dwServiceCount++)
+ {
+ lpService = lpServicesArray[dwServiceCount];
+
+ /* Copy the status info */
+ memcpy(&lpServicesPtr->ServiceStatus,
+ &lpService->Status,
+ sizeof(SERVICE_STATUS));
+
+ /* Copy display name */
+ WideCharToMultiByte(CP_ACP,
+ 0,
+ lpService->lpDisplayName,
+ -1,
+ lpStr,
+ wcslen(lpService->lpDisplayName),
+ 0,
+ 0);
+ lpServicesPtr->lpDisplayName = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServices);
+ lpStr += strlen(lpStr) + 1;
+
+ /* Copy service name */
+ WideCharToMultiByte(CP_ACP,
+ 0,
+ lpService->lpServiceName,
+ -1,
+ lpStr,
+ wcslen(lpService->lpServiceName),
+ 0,
+ 0);
+ lpServicesPtr->lpServiceName = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServices);
+ lpStr += strlen(lpStr) + 1;
+
+ lpServicesPtr ++;
+ }
+
+ *lpServicesReturned = dwServicesReturned;
+
+Done:
+ if (lpServicesArray)
+ HeapFree(GetProcessHeap(), 0, lpServicesArray);
+
+ RegCloseKey(hServicesKey);
+
+ DPRINT("REnumDependentServicesA() done (Error %lu)\n", dwError);
+
+ return dwError;
+}
+
+
+/* Function 26 */
+DWORD REnumServicesStatusA(
+ SC_RPC_HANDLE hSCManager,
+ DWORD dwServiceType,
+ DWORD dwServiceState,
+ LPBYTE lpBuffer,
+ DWORD dwBufSize,
+ LPBOUNDED_DWORD_256K pcbBytesNeeded,
+ LPBOUNDED_DWORD_256K lpServicesReturned,
+ LPBOUNDED_DWORD_256K lpResumeHandle)
+{
+ LPENUM_SERVICE_STATUSW lpStatusPtrW = NULL;
+ LPENUM_SERVICE_STATUSA lpStatusPtrA = NULL;
+ LPWSTR lpStringPtrW;
+ LPSTR lpStringPtrA;
+ DWORD dwError;
+ DWORD dwServiceCount;
+
+ DPRINT("REnumServicesStatusA() called\n");
+
+ if ((dwBufSize > 0) && (lpBuffer))
+ {
+ lpStatusPtrW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufSize);
+ if (!lpStatusPtrW)
+ {
+ DPRINT("Failed to allocate buffer!\n");
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+ }
+
+ dwError = REnumServicesStatusW(hSCManager,
+ dwServiceType,
+ dwServiceState,
+ (LPBYTE)lpStatusPtrW,
+ dwBufSize,
+ pcbBytesNeeded,
+ lpServicesReturned,
+ lpResumeHandle);
+
+ /* if no services were returned then we are Done */
+ if (*lpServicesReturned == 0)
+ goto Done;
+
+ lpStatusPtrA = (LPENUM_SERVICE_STATUSA)lpBuffer;
+ lpStringPtrA = (LPSTR)((ULONG_PTR)lpBuffer +
+ *lpServicesReturned * sizeof(ENUM_SERVICE_STATUSA));
+ lpStringPtrW = (LPWSTR)((ULONG_PTR)lpStatusPtrW +
+ *lpServicesReturned * sizeof(ENUM_SERVICE_STATUSW));
+
+ for (dwServiceCount = 0; dwServiceCount < *lpServicesReturned; dwServiceCount++)
+ {
+ /* Copy the service name */
+ WideCharToMultiByte(CP_ACP,
+ 0,
+ lpStringPtrW,
+ -1,
+ lpStringPtrA,
+ wcslen(lpStringPtrW),
+ 0,
+ 0);
+
+ lpStatusPtrA->lpServiceName = (LPSTR)((ULONG_PTR)lpStringPtrA - (ULONG_PTR)lpBuffer);
+ lpStringPtrA += wcslen(lpStringPtrW) + 1;
+ lpStringPtrW += wcslen(lpStringPtrW) + 1;
+
+ /* Copy the display name */
+ WideCharToMultiByte(CP_ACP,
+ 0,
+ lpStringPtrW,
+ -1,
+ lpStringPtrA,
+ wcslen(lpStringPtrW),
+ 0,
+ 0);
+
+ lpStatusPtrA->lpDisplayName = (LPSTR)((ULONG_PTR)lpStringPtrA - (ULONG_PTR)lpBuffer);
+ lpStringPtrA += wcslen(lpStringPtrW) + 1;
+ lpStringPtrW += wcslen(lpStringPtrW) + 1;
+
+ /* Copy the status information */
+ memcpy(&lpStatusPtrA->ServiceStatus,
+ &lpStatusPtrW->ServiceStatus,
+ sizeof(SERVICE_STATUS));
+
+ lpStatusPtrA++;
+ }
+
+Done:;
+ if (lpStatusPtrW)
+ HeapFree(GetProcessHeap(), 0, lpStatusPtrW);
+
+ DPRINT("REnumServicesStatusA() done (Error %lu)\n", dwError);
+
+ return dwError;
+}
+
+
+/* Function 27 */
+DWORD ROpenSCManagerA(
+ LPSTR lpMachineName,
+ LPSTR lpDatabaseName,
+ DWORD dwDesiredAccess,
+ LPSC_RPC_HANDLE lpScHandle)
+{
+ UNICODE_STRING MachineName;
+ UNICODE_STRING DatabaseName;
+ DWORD dwError;
+
+ DPRINT("ROpenSCManagerA() called\n");
+
+ if (lpMachineName)
+ RtlCreateUnicodeStringFromAsciiz(&MachineName,
+ lpMachineName);
+
+ if (lpDatabaseName)
+ RtlCreateUnicodeStringFromAsciiz(&DatabaseName,
+ lpDatabaseName);
+
+ dwError = ROpenSCManagerW(lpMachineName ? MachineName.Buffer : NULL,
+ lpDatabaseName ? DatabaseName.Buffer : NULL,
+ dwDesiredAccess,
+ lpScHandle);
+
+ if (lpMachineName)
+ RtlFreeUnicodeString(&MachineName);
+
+ if (lpDatabaseName)
+ RtlFreeUnicodeString(&DatabaseName);
+
+ return dwError;
+}
+
+
+/* Function 28 */
+DWORD ROpenServiceA(
+ SC_RPC_HANDLE hSCManager,
+ LPSTR lpServiceName,
+ DWORD dwDesiredAccess,
+ LPSC_RPC_HANDLE lpServiceHandle)
+{
+ UNICODE_STRING ServiceName;
+ DWORD dwError;
+
+ DPRINT("ROpenServiceA() called\n");
+
+ if (lpServiceName)
+ RtlCreateUnicodeStringFromAsciiz(&ServiceName,
+ lpServiceName);
+
+ dwError = ROpenServiceW(hSCManager,
+ lpServiceName ? ServiceName.Buffer : NULL,
+ dwDesiredAccess,
+ lpServiceHandle);
+
+ if (lpServiceName)
+ RtlFreeUnicodeString(&ServiceName);
+
+ return dwError;
+}
+
+
+/* Function 29 */
+DWORD RQueryServiceConfigA(
+ SC_RPC_HANDLE hService,
+ LPQUERY_SERVICE_CONFIGA lpServiceConfig,
+ DWORD cbBufSize,
+ LPBOUNDED_DWORD_8K pcbBytesNeeded)
+{
+ DWORD dwError = ERROR_SUCCESS;
+ PSERVICE_HANDLE hSvc;
+ PSERVICE lpService = NULL;
+ HKEY hServiceKey = NULL;
+ LPWSTR lpImagePath = NULL;
+ LPWSTR lpServiceStartName = NULL;
+ LPWSTR lpDependencies = NULL;
+ DWORD dwDependenciesLength = 0;
+ DWORD dwRequiredSize;
+ LPQUERY_SERVICE_CONFIGA lpConfig = NULL;
+ CHAR lpEmptyString[]={0,0};
+ LPSTR lpStr;
+
+ DPRINT("RQueryServiceConfigA() called\n");
+
+ if (ScmShutdown)
+ return ERROR_SHUTDOWN_IN_PROGRESS;
+
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
+ {
+ DPRINT1("Invalid service handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
+ SERVICE_QUERY_CONFIG))
+ {
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ return ERROR_ACCESS_DENIED;
+ }
+
+ lpService = hSvc->ServiceEntry;
+ if (lpService == NULL)
+ {
+ DPRINT("lpService == NULL!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ /* FIXME: Lock the service database shared */
+
+ dwError = ScmOpenServiceKey(lpService->lpServiceName,
+ KEY_READ,
+ &hServiceKey);
+ if (dwError != ERROR_SUCCESS)
+ goto Done;
+
+ /* Read the image path */
+ dwError = ScmReadString(hServiceKey,
+ L"ImagePath",
+ &lpImagePath);
+ if (dwError != ERROR_SUCCESS)
+ goto Done;
+
+ /* Read the service start name */
+ ScmReadString(hServiceKey,
+ L"ObjectName",
+ &lpServiceStartName);
+
+ /* Read the dependencies */
+ ScmReadDependencies(hServiceKey,
+ &lpDependencies,
+ &dwDependenciesLength);
+
+ dwRequiredSize = sizeof(QUERY_SERVICE_CONFIGW);
+
+ if (lpImagePath != NULL)
+ dwRequiredSize += wcslen(lpImagePath) + 1;
+ else
+ dwRequiredSize += 2;
+
+ if ((lpService->lpGroup != NULL) && (lpService->lpGroup->lpGroupName != NULL))
+ dwRequiredSize += wcslen(lpService->lpGroup->lpGroupName) + 1;
+ else
+ dwRequiredSize += 2;
+
+ /* Add Dependencies length */
+ if (lpDependencies != NULL)
+ dwRequiredSize += dwDependenciesLength;
+ else
+ dwRequiredSize += 2;
+
+ if (lpServiceStartName != NULL)
+ dwRequiredSize += wcslen(lpServiceStartName) + 1;
+ else
+ dwRequiredSize += 2;
+
+ if (lpService->lpDisplayName != NULL)
+ dwRequiredSize += wcslen(lpService->lpDisplayName) + 1;
+ else
+ dwRequiredSize += 2;
+
+ if (lpServiceConfig == NULL || cbBufSize < dwRequiredSize)
+ {
+ dwError = ERROR_INSUFFICIENT_BUFFER;
+ }
+ else
+ {
+ lpConfig = (LPQUERY_SERVICE_CONFIGA)lpServiceConfig;
+ lpConfig->dwServiceType = lpService->Status.dwServiceType;
+ lpConfig->dwStartType = lpService->dwStartType;
+ lpConfig->dwErrorControl = lpService->dwErrorControl;
+ lpConfig->dwTagId = lpService->dwTag;
+
+ lpStr = (LPSTR)(lpServiceConfig + 1);
+
+ /* NOTE: Strings that are NULL for QUERY_SERVICE_CONFIG are pointers to empty strings.
+ Verified in WINXP*/
+
+ if (lpImagePath)
+ {
+ WideCharToMultiByte(CP_ACP,
+ 0,
+ lpImagePath,
+ -1,
+ lpStr,
+ wcslen(lpImagePath) + 1,
+ 0,
+ 0);
+ }
+ else
+ {
+ strcpy(lpStr, lpEmptyString);
+ }
+
+ lpConfig->lpBinaryPathName = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
+ lpStr += (strlen((LPSTR)lpStr) + 1);
+
+ if (lpService->lpGroup && lpService->lpGroup->lpGroupName)
+ {
+ WideCharToMultiByte(CP_ACP,
+ 0,
+ lpService->lpGroup->lpGroupName,
+ -1,
+ lpStr,
+ wcslen(lpService->lpGroup->lpGroupName) + 1,
+ 0,
+ 0);
+ }
+ else
+ {
+ strcpy(lpStr, lpEmptyString);
+ }
+
+ lpConfig->lpLoadOrderGroup = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
+ lpStr += (strlen(lpStr) + 1);
+
+ /* Append Dependencies */
+ if (lpDependencies)
+ {
+ WideCharToMultiByte(CP_ACP,
+ 0,
+ lpDependencies,
+ dwDependenciesLength,
+ lpStr,
+ dwDependenciesLength,
+ 0,
+ 0);
+ }
+ else
+ {
+ strcpy(lpStr, lpEmptyString);
+ }
+
+ lpConfig->lpDependencies = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
+ if (lpDependencies)
+ lpStr += dwDependenciesLength;
+ else
+ lpStr += (strlen(lpStr) + 1);
+
+ if (lpServiceStartName)
+ {
+ WideCharToMultiByte(CP_ACP,
+ 0,
+ lpServiceStartName,
+ -1,
+ lpStr,
+ wcslen(lpServiceStartName) + 1,
+ 0,
+ 0);
+ }
+ else
+ {
+ strcpy(lpStr, lpEmptyString);
+ }
+
+ lpConfig->lpServiceStartName = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
+ lpStr += (strlen(lpStr) + 1);
+
+ if (lpService->lpDisplayName)
+ {
+ WideCharToMultiByte(CP_ACP,
+ 0,
+ lpService->lpDisplayName,
+ -1,
+ lpStr,
+ wcslen(lpService->lpDisplayName) + 1,
+ 0,
+ 0);
+ }
+ else
+ {
+ strcpy(lpStr, lpEmptyString);
+ }
+
+ lpConfig->lpDisplayName = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpConfig);
+ }
+
+ if (pcbBytesNeeded != NULL)
+ *pcbBytesNeeded = dwRequiredSize;
+
+Done:;
+ if (lpImagePath != NULL)
+ HeapFree(GetProcessHeap(), 0, lpImagePath);
+
+ if (lpServiceStartName != NULL)
+ HeapFree(GetProcessHeap(), 0, lpServiceStartName);
+
+ if (lpDependencies != NULL)
+ HeapFree(GetProcessHeap(), 0, lpDependencies);
+
+ if (hServiceKey != NULL)
+ RegCloseKey(hServiceKey);
+
+ /* FIXME: Unlock the service database */
+
+ DPRINT("RQueryServiceConfigA() done\n");
+
+ return dwError;
+}
+
+
+/* Function 30 */
+DWORD RQueryServiceLockStatusA(
+ SC_RPC_HANDLE hSCManager,
+ LPQUERY_SERVICE_LOCK_STATUSA lpLockStatus,
+ DWORD cbBufSize,
+ LPBOUNDED_DWORD_4K pcbBytesNeeded)
+{
+ UNIMPLEMENTED;
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 31 */
+DWORD RStartServiceA(
+ SC_RPC_HANDLE hService,
+ DWORD argc,
+ LPSTRING_PTRSA argv)
+{
+ DWORD dwError = ERROR_SUCCESS;
+ PSERVICE_HANDLE hSvc;
+ PSERVICE lpService = NULL;
+
+ DPRINT("RStartServiceA() called\n");
+
+ if (ScmShutdown)
+ return ERROR_SHUTDOWN_IN_PROGRESS;
+
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
+ {
+ DPRINT1("Invalid service handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
+ SERVICE_START))
+ {
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ return ERROR_ACCESS_DENIED;
+ }
+
+ lpService = hSvc->ServiceEntry;
+ if (lpService == NULL)
+ {
+ DPRINT("lpService == NULL!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ if (lpService->dwStartType == SERVICE_DISABLED)
+ return ERROR_SERVICE_DISABLED;
+
+ if (lpService->bDeleted)
+ return ERROR_SERVICE_MARKED_FOR_DELETE;
+
+ /* FIXME: Convert argument vector to Unicode */
+
+ /* Start the service */
+ dwError = ScmStartService(lpService, 0, NULL);
+
+ /* FIXME: Free argument vector */
+
+ return dwError;
+}
+
+
+/* Function 32 */
+DWORD RGetServiceDisplayNameA(
+ SC_RPC_HANDLE hSCManager,
+ LPCSTR lpServiceName,
+ LPSTR lpDisplayName,
+ LPBOUNDED_DWORD_4K lpcchBuffer)
+{
+// PMANAGER_HANDLE hManager;
+ PSERVICE lpService = NULL;
+ DWORD dwLength;
+ DWORD dwError;
+ LPWSTR lpServiceNameW;
+
+ DPRINT("RGetServiceDisplayNameA() called\n");
+ DPRINT("hSCManager = %p\n", hSCManager);
+ DPRINT("lpServiceName: %s\n", lpServiceName);
+ DPRINT("lpDisplayName: %p\n", lpDisplayName);
+ DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer);
+
+// hManager = (PMANAGER_HANDLE)hSCManager;
+// if (hManager->Handle.Tag != MANAGER_TAG)
+// {
+// DPRINT("Invalid manager handle!\n");
+// return ERROR_INVALID_HANDLE;
+// }
+
+ if (lpServiceName != NULL)
+ {
+ dwLength = strlen(lpServiceName) + 1;
+ lpServiceNameW = HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ dwLength * sizeof(WCHAR));
+ if (!lpServiceNameW)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ MultiByteToWideChar(CP_ACP,
+ 0,
+ lpServiceName,
+ -1,
+ lpServiceNameW,
+ dwLength);
+
+ lpService = ScmGetServiceEntryByName(lpServiceNameW);
+
+ HeapFree(GetProcessHeap(), 0, lpServiceNameW);
+ }
+
+ if (lpService == NULL)
+ {
+ DPRINT("Could not find a service!\n");
+
+ /* If the service could not be found and lpcchBuffer is 0, windows
+ puts null in lpDisplayName and puts 1 in lpcchBuffer */
+ if (*lpcchBuffer == 0)
+ {
+ *lpcchBuffer = 1;
+ if (lpDisplayName != NULL)
+ {
+ *lpDisplayName = '\0';
+ }
+ }
+ return ERROR_SERVICE_DOES_NOT_EXIST;
+ }
+
+ if (!lpService->lpDisplayName)
+ {
+ dwLength = wcslen(lpService->lpServiceName);
+ if (lpDisplayName != NULL &&
+ *lpcchBuffer > dwLength)
+ {
+ WideCharToMultiByte(CP_ACP,
+ 0,
+ lpService->lpServiceName,
+ wcslen(lpService->lpServiceName),
+ lpDisplayName,
+ dwLength + 1,
+ NULL,
+ NULL);
+ return ERROR_SUCCESS;
+ }
+ }
+ else
+ {
+ dwLength = wcslen(lpService->lpDisplayName);
+ if (lpDisplayName != NULL &&
+ *lpcchBuffer > dwLength)
+ {
+ WideCharToMultiByte(CP_ACP,
+ 0,
+ lpService->lpDisplayName,
+ wcslen(lpService->lpDisplayName),
+ lpDisplayName,
+ dwLength + 1,
+ NULL,
+ NULL);
+ return ERROR_SUCCESS;
+ }
+ }
+
+ dwError = (*lpcchBuffer > dwLength) ? ERROR_SUCCESS : ERROR_INSUFFICIENT_BUFFER;
+
+ *lpcchBuffer = dwLength * 2;
+
+ return dwError;
+}
+
+
+/* Function 33 */
+DWORD RGetServiceKeyNameA(
+ SC_RPC_HANDLE hSCManager,
+ LPCSTR lpDisplayName,
+ LPSTR lpServiceName,
+ LPBOUNDED_DWORD_4K lpcchBuffer)
+{
+ PSERVICE lpService;
+ DWORD dwLength;
+ DWORD dwError;
+ LPWSTR lpDisplayNameW;
+
+ DPRINT("RGetServiceKeyNameA() called\n");
+ DPRINT("hSCManager = %p\n", hSCManager);
+ DPRINT("lpDisplayName: %s\n", lpDisplayName);
+ DPRINT("lpServiceName: %p\n", lpServiceName);
+ DPRINT("*lpcchBuffer: %lu\n", *lpcchBuffer);
+
+ dwLength = strlen(lpDisplayName) + 1;
+ lpDisplayNameW = HeapAlloc(GetProcessHeap(),
+ HEAP_ZERO_MEMORY,
+ dwLength * sizeof(WCHAR));
+ if (!lpDisplayNameW)
+ return ERROR_NOT_ENOUGH_MEMORY;
+
+ MultiByteToWideChar(CP_ACP,
+ 0,
+ lpDisplayName,
+ -1,
+ lpDisplayNameW,
+ dwLength);
+
+ lpService = ScmGetServiceEntryByDisplayName(lpDisplayNameW);
+
+ HeapFree(GetProcessHeap(), 0, lpDisplayNameW);
+
+ if (lpService == NULL)
+ {
+ DPRINT("Could not find the service!\n");
+
+ /* If the service could not be found and lpcchBuffer is 0,
+ put null in lpDisplayName and puts 1 in lpcchBuffer, verified WINXP. */
+ if (*lpcchBuffer == 0)
+ {
+ *lpcchBuffer = 1;
+ if (lpServiceName != NULL)
+ {
+ *lpServiceName = '\0';
+ }
+ }
+
+ return ERROR_SERVICE_DOES_NOT_EXIST;
+ }
+
+ dwLength = wcslen(lpService->lpServiceName);
+ if (lpServiceName != NULL &&
+ *lpcchBuffer > dwLength)
+ {
+ WideCharToMultiByte(CP_ACP,
+ 0,
+ lpService->lpServiceName,
+ wcslen(lpService->lpServiceName),
+ lpServiceName,
+ dwLength + 1,
+ NULL,
+ NULL);
+ return ERROR_SUCCESS;
+ }
+
+ dwError = (*lpcchBuffer > dwLength) ? ERROR_SUCCESS : ERROR_INSUFFICIENT_BUFFER;
+
+ *lpcchBuffer = dwLength * 2;
+
+ return dwError;
+}
+
+
+/* Function 34 */
+DWORD RI_ScGetCurrentGroupStateW(
+ SC_RPC_HANDLE hSCManager,
+ LPWSTR lpLoadOrderGroup,
+ LPDWORD lpState)
+{
+ UNIMPLEMENTED;
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 35 */
+DWORD REnumServiceGroupW(
+ SC_RPC_HANDLE hSCManager,
+ DWORD dwServiceType,
+ DWORD dwServiceState,
+ LPBYTE lpBuffer,
+ DWORD cbBufSize,
+ LPBOUNDED_DWORD_256K pcbBytesNeeded,
+ LPBOUNDED_DWORD_256K lpServicesReturned,
+ LPBOUNDED_DWORD_256K lpResumeIndex,
+ LPCWSTR pszGroupName)
+{
+ UNIMPLEMENTED;
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+//
+// WARNING: This function is untested
+//
+/* Function 36 */
+DWORD RChangeServiceConfig2A(
+ SC_RPC_HANDLE hService,
+ SC_RPC_CONFIG_INFOA Info)
+{
+ SC_RPC_CONFIG_INFOW InfoW;
+ DWORD dwRet, dwLength;
+ PVOID ptr = NULL;
+
+ DPRINT("RChangeServiceConfig2A() called\n");
+ DPRINT("dwInfoLevel = %lu\n", Info.dwInfoLevel);
+
+ InfoW.dwInfoLevel = Info.dwInfoLevel;
+
+ if (InfoW.dwInfoLevel == SERVICE_CONFIG_DESCRIPTION)
+ {
+ LPSERVICE_DESCRIPTIONW lpServiceDescriptonW;
+ LPSERVICE_DESCRIPTIONA lpServiceDescriptonA;
+
+ lpServiceDescriptonA = Info.psd;
+
+ ///if (lpServiceDescriptonA &&
+ ///lpServiceDescriptonA->lpDescription)
+ ///{
+ dwLength = (strlen(Info.lpDescription) + 1) * sizeof(WCHAR);
+
+ lpServiceDescriptonW = HeapAlloc(GetProcessHeap(),
+ 0,
+ dwLength + sizeof(SERVICE_DESCRIPTIONW));
+ if (!lpServiceDescriptonW)
+ {
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ lpServiceDescriptonW->lpDescription = (LPWSTR)(lpServiceDescriptonW + 1);
+
+ MultiByteToWideChar(CP_ACP,
+ 0,
+ Info.lpDescription,
+ -1,
+ lpServiceDescriptonW->lpDescription,
+ dwLength);
+
+ ptr = lpServiceDescriptonW;
+ InfoW.psd = lpServiceDescriptonW;
+ ///}
+ }
+ else if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
+ {
+ LPSERVICE_FAILURE_ACTIONSW lpServiceFailureActionsW;
+ LPSERVICE_FAILURE_ACTIONSA lpServiceFailureActionsA;
+ DWORD dwRebootLen = 0;
+ DWORD dwCommandLen = 0;
+
+ lpServiceFailureActionsA = Info.psfa;
+
+ if (lpServiceFailureActionsA)
+ {
+ if (lpServiceFailureActionsA->lpRebootMsg)
+ {
+ dwRebootLen = (strlen(lpServiceFailureActionsA->lpRebootMsg) + 1) * sizeof(WCHAR);
+ }
+ if (lpServiceFailureActionsA->lpCommand)
+ {
+ dwCommandLen = (strlen(lpServiceFailureActionsA->lpCommand) + 1) * sizeof(WCHAR);
+ }
+ dwLength = dwRebootLen + dwCommandLen + sizeof(SERVICE_FAILURE_ACTIONSW);
+
+ lpServiceFailureActionsW = HeapAlloc(GetProcessHeap(),
+ 0,
+ dwLength);
+ if (!lpServiceFailureActionsW)
+ {
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ lpServiceFailureActionsW->cActions = lpServiceFailureActionsA->cActions;
+ lpServiceFailureActionsW->dwResetPeriod = lpServiceFailureActionsA->dwResetPeriod;
+ CopyMemory(lpServiceFailureActionsW->lpsaActions, lpServiceFailureActionsA->lpsaActions, sizeof(SC_ACTION));
+
+ if (lpServiceFailureActionsA->lpRebootMsg)
+ {
+ MultiByteToWideChar(CP_ACP,
+ 0,
+ lpServiceFailureActionsA->lpRebootMsg,
+ -1,
+ lpServiceFailureActionsW->lpRebootMsg,
+ dwRebootLen);
+ }
+
+ if (lpServiceFailureActionsA->lpCommand)
+ {
+ MultiByteToWideChar(CP_ACP,
+ 0,
+ lpServiceFailureActionsA->lpCommand,
+ -1,
+ lpServiceFailureActionsW->lpCommand,
+ dwCommandLen);
+ }
+
+ ptr = lpServiceFailureActionsW;
+ }
+ }
+
+ dwRet = RChangeServiceConfig2W(hService, InfoW);
+
+ HeapFree(GetProcessHeap(), 0, ptr);
+
+ return dwRet;
+}
+
+
+/* Function 37 */
+DWORD RChangeServiceConfig2W(
+ SC_RPC_HANDLE hService,
+ SC_RPC_CONFIG_INFOW Info)
+{
+ DWORD dwError = ERROR_SUCCESS;
+ PSERVICE_HANDLE hSvc;
+ PSERVICE lpService = NULL;
+ HKEY hServiceKey = NULL;
+
+ DPRINT("RChangeServiceConfig2W() called\n");
+ DPRINT("dwInfoLevel = %lu\n", Info.dwInfoLevel);
+
+ if (ScmShutdown)
+ return ERROR_SHUTDOWN_IN_PROGRESS;
+
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
+ {
+ DPRINT1("Invalid service handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
+ SERVICE_CHANGE_CONFIG))
+ {
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ return ERROR_ACCESS_DENIED;
+ }
+
+ lpService = hSvc->ServiceEntry;
+ if (lpService == NULL)
+ {
+ DPRINT("lpService == NULL!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ /* FIXME: Lock database exclusively */
+
+ if (lpService->bDeleted)
+ {
+ /* FIXME: Unlock database */
+ DPRINT("The service has already been marked for delete!\n");
+ return ERROR_SERVICE_MARKED_FOR_DELETE;
+ }
+
+ /* Open the service key */
+ dwError = ScmOpenServiceKey(lpService->szServiceName,
+ KEY_SET_VALUE,
+ &hServiceKey);
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+
+ if (Info.dwInfoLevel == SERVICE_CONFIG_DESCRIPTION)
+ {
+ LPSERVICE_DESCRIPTIONW lpServiceDescription;
+
+ lpServiceDescription = (LPSERVICE_DESCRIPTIONW)Info.psd;
+ lpServiceDescription->lpDescription = (LPWSTR)((ULONG_PTR)lpServiceDescription + sizeof(LPSERVICE_DESCRIPTIONW));
+
+ if (lpServiceDescription != NULL &&
+ lpServiceDescription->lpDescription != NULL)
+ {
+ DPRINT("Setting value %S\n", lpServiceDescription->lpDescription);
+ RegSetValueExW(hServiceKey,
+ L"Description",
+ 0,
+ REG_SZ,
+ (LPBYTE)lpServiceDescription->lpDescription,
+ (wcslen(lpServiceDescription->lpDescription) + 1) * sizeof(WCHAR));
+
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+ }
+ }
+ else if (Info.dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
+ {
+ UNIMPLEMENTED;
+ dwError = ERROR_CALL_NOT_IMPLEMENTED;
+ goto done;
+ }
+
+done:
+ /* FIXME: Unlock database */
+ if (hServiceKey != NULL)
+ RegCloseKey(hServiceKey);
+
+ DPRINT("RChangeServiceConfig2W() done (Error %lu)\n", dwError);
+
+ return dwError;
+}
+
+
+/* Function 38 */
+DWORD RQueryServiceConfig2A(
+ SC_RPC_HANDLE hService,
+ DWORD dwInfoLevel,
+ LPBYTE lpBuffer,
+ DWORD cbBufSize,
+ LPBOUNDED_DWORD_8K pcbBytesNeeded)
+{
+ DWORD dwError = ERROR_SUCCESS;
+ PSERVICE_HANDLE hSvc;
+ PSERVICE lpService = NULL;
+ HKEY hServiceKey = NULL;
+ LPWSTR lpDescriptionW = NULL;
+ LPSTR lpDescription = NULL;
+
+ DPRINT("RQueryServiceConfig2A() called hService %p dwInfoLevel %u, lpBuffer %p cbBufSize %u pcbBytesNeeded %p\n",
+ hService, dwInfoLevel, lpBuffer, cbBufSize, pcbBytesNeeded);
+
+ if (!lpBuffer)
+ return ERROR_INVALID_ADDRESS;
+
+ if (ScmShutdown)
+ return ERROR_SHUTDOWN_IN_PROGRESS;
+
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
+ {
+ DPRINT1("Invalid service handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
+ SERVICE_QUERY_CONFIG))
+ {
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ return ERROR_ACCESS_DENIED;
+ }
+
+ lpService = hSvc->ServiceEntry;
+ if (lpService == NULL)
+ {
+ DPRINT("lpService == NULL!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ /* FIXME: Lock the service database shared */
+
+ dwError = ScmOpenServiceKey(lpService->lpServiceName,
+ KEY_READ,
+ &hServiceKey);
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+
+ if (dwInfoLevel == SERVICE_CONFIG_DESCRIPTION)
+ {
+ LPSERVICE_DESCRIPTIONA lpServiceDescription = (LPSERVICE_DESCRIPTIONA)lpBuffer;
+ LPSTR lpStr;
+
+ *pcbBytesNeeded = sizeof(SERVICE_DESCRIPTIONA);
+
+ dwError = ScmReadString(hServiceKey,
+ L"Description",
+ &lpDescriptionW);
+ if (dwError == ERROR_SUCCESS)
+ {
+ *pcbBytesNeeded += ((wcslen(lpDescriptionW) + 1) * sizeof(WCHAR));
+ }
+
+ if (cbBufSize >= *pcbBytesNeeded)
+ {
+
+ if (dwError == ERROR_SUCCESS)
+ {
+ lpStr = (LPSTR)(lpServiceDescription + 1);
+
+ WideCharToMultiByte(CP_ACP,
+ 0,
+ lpDescriptionW,
+ -1,
+ lpStr,
+ wcslen(lpDescriptionW),
+ NULL,
+ NULL);
+ lpServiceDescription->lpDescription = (LPSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription);
+ }
+ else
+ {
+ lpServiceDescription->lpDescription = NULL;
+ goto done;
+ }
+ }
+ else
+ {
+ dwError = ERROR_INSUFFICIENT_BUFFER;
+ goto done;
+ }
+ }
+ else if (dwInfoLevel & SERVICE_CONFIG_FAILURE_ACTIONS)
+ {
+ UNIMPLEMENTED;
+ dwError = ERROR_CALL_NOT_IMPLEMENTED;
+ goto done;
+ }
+
+done:
+ if (lpDescription != NULL)
+ HeapFree(GetProcessHeap(), 0, lpDescription);
+
+ if (hServiceKey != NULL)
+ RegCloseKey(hServiceKey);
+
+ /* FIXME: Unlock database */
+
+ DPRINT("RQueryServiceConfig2W() done (Error %lu)\n", dwError);
+
+ return dwError;
+}
+
+
+/* Function 39 */
+DWORD RQueryServiceConfig2W(
+ SC_RPC_HANDLE hService,
+ DWORD dwInfoLevel,
+ LPBYTE lpBuffer,
+ DWORD cbBufSize,
+ LPBOUNDED_DWORD_8K pcbBytesNeeded)
+{
+ DWORD dwError = ERROR_SUCCESS;
+ PSERVICE_HANDLE hSvc;
+ PSERVICE lpService = NULL;
+ HKEY hServiceKey = NULL;
+ DWORD dwRequiredSize;
+ LPWSTR lpDescription = NULL;
+ LPWSTR lpFailureCommand = NULL;
+ LPWSTR lpRebootMessage = NULL;
+
+ DPRINT("RQueryServiceConfig2W() called\n");
+
+ if (!lpBuffer)
+ return ERROR_INVALID_ADDRESS;
+
+ if (ScmShutdown)
+ return ERROR_SHUTDOWN_IN_PROGRESS;
+
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
+ {
+ DPRINT1("Invalid service handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
+ SERVICE_QUERY_CONFIG))
+ {
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ return ERROR_ACCESS_DENIED;
+ }
+
+ lpService = hSvc->ServiceEntry;
+ if (lpService == NULL)
+ {
+ DPRINT("lpService == NULL!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ /* FIXME: Lock the service database shared */
+
+ dwError = ScmOpenServiceKey(lpService->lpServiceName,
+ KEY_READ,
+ &hServiceKey);
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+
+ if (dwInfoLevel == SERVICE_CONFIG_DESCRIPTION)
+ {
+ LPSERVICE_DESCRIPTIONW lpServiceDescription = (LPSERVICE_DESCRIPTIONW)lpBuffer;
+ LPWSTR lpStr;
+
+ dwError = ScmReadString(hServiceKey,
+ L"Description",
+ &lpDescription);
+ if (dwError != ERROR_SUCCESS)
+ goto done;
+
+ dwRequiredSize = sizeof(SERVICE_DESCRIPTIONW) + ((wcslen(lpDescription) + 1) * sizeof(WCHAR));
+
+ if (cbBufSize < dwRequiredSize)
+ {
+ *pcbBytesNeeded = dwRequiredSize;
+ dwError = ERROR_INSUFFICIENT_BUFFER;
+ goto done;
+ }
+
+ lpStr = (LPWSTR)(lpServiceDescription + 1);
+ wcscpy(lpStr, lpDescription);
+ lpServiceDescription->lpDescription = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpServiceDescription);
+ }
+ else if (dwInfoLevel == SERVICE_CONFIG_FAILURE_ACTIONS)
+ {
+ LPWSTR lpStr;
+ LPSERVICE_FAILURE_ACTIONSW lpFailureActions = (LPSERVICE_FAILURE_ACTIONSW)lpBuffer;
+
+ UNIMPLEMENTED;
+
+ dwError = ScmReadString(hServiceKey,
+ L"FailureCommand",
+ &lpFailureCommand);
+
+ dwError = ScmReadString(hServiceKey,
+ L"RebootMessage",
+ &lpRebootMessage);
+
+ dwRequiredSize = sizeof(SERVICE_FAILURE_ACTIONSW);
+
+ if (lpFailureCommand)
+ dwRequiredSize += (wcslen(lpFailureCommand) + 1) * sizeof(WCHAR);
+
+ if (lpRebootMessage)
+ dwRequiredSize += (wcslen(lpRebootMessage) + 1) * sizeof(WCHAR);
+
+ if (cbBufSize < dwRequiredSize)
+ {
+ *pcbBytesNeeded = dwRequiredSize;
+ dwError = ERROR_INSUFFICIENT_BUFFER;
+ goto done;
+ }
+
+ lpFailureActions->cActions = 0;
+ lpFailureActions->dwResetPeriod = 0;
+ lpFailureActions->lpCommand = NULL;
+ lpFailureActions->lpRebootMsg = NULL;
+ lpFailureActions->lpsaActions = NULL;
+
+ lpStr = (LPWSTR)(lpFailureActions + 1);
+ if (lpRebootMessage)
+ {
+ wcscpy(lpStr, lpRebootMessage);
+ lpFailureActions->lpRebootMsg = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpRebootMessage);
+ lpStr += wcslen(lpRebootMessage) + 1;
+ }
+
+ if (lpFailureCommand)
+ {
+ wcscpy(lpStr, lpFailureCommand);
+ lpFailureActions->lpCommand = (LPWSTR)((ULONG_PTR)lpStr - (ULONG_PTR)lpFailureCommand);
+ lpStr += wcslen(lpRebootMessage) + 1;
+ }
+ dwError = STATUS_SUCCESS;
+ goto done;
+ }
+
+done:
+ if (lpDescription != NULL)
+ HeapFree(GetProcessHeap(), 0, lpDescription);
+
+ if (lpRebootMessage != NULL)
+ HeapFree(GetProcessHeap(), 0, lpRebootMessage);
+
+ if (lpFailureCommand != NULL)
+ HeapFree(GetProcessHeap(), 0, lpFailureCommand);
+
+ if (hServiceKey != NULL)
+ RegCloseKey(hServiceKey);
+
+ /* FIXME: Unlock database */
+
+ DPRINT("RQueryServiceConfig2W() done (Error %lu)\n", dwError);
+
+ return dwError;
+}
+
+
+/* Function 40 */
+DWORD RQueryServiceStatusEx(
+ SC_RPC_HANDLE hService,
+ SC_STATUS_TYPE InfoLevel,
+ LPBYTE lpBuffer,
+ DWORD cbBufSize,
+ LPBOUNDED_DWORD_8K pcbBytesNeeded)
+{
+ LPSERVICE_STATUS_PROCESS lpStatus;
+ PSERVICE_HANDLE hSvc;
+ PSERVICE lpService;
+
+ DPRINT("RQueryServiceStatusEx() called\n");
+
+ if (ScmShutdown)
+ return ERROR_SHUTDOWN_IN_PROGRESS;
+
+ if (InfoLevel != SC_STATUS_PROCESS_INFO)
+ return ERROR_INVALID_LEVEL;
+
+ *pcbBytesNeeded = sizeof(SERVICE_STATUS_PROCESS);
+
+ if (cbBufSize < sizeof(SERVICE_STATUS_PROCESS))
+ return ERROR_INSUFFICIENT_BUFFER;
+
+ hSvc = ScmGetServiceFromHandle(hService);
+ if (hSvc == NULL)
+ {
+ DPRINT1("Invalid service handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ if (!RtlAreAllAccessesGranted(hSvc->Handle.DesiredAccess,
+ SERVICE_QUERY_STATUS))
+ {
+ DPRINT("Insufficient access rights! 0x%lx\n", hSvc->Handle.DesiredAccess);
+ return ERROR_ACCESS_DENIED;
+ }
+
+ lpService = hSvc->ServiceEntry;
+ if (lpService == NULL)
+ {
+ DPRINT("lpService == NULL!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ lpStatus = (LPSERVICE_STATUS_PROCESS)lpBuffer;
+
+ /* Return service status information */
+ RtlCopyMemory(lpStatus,
+ &lpService->Status,
+ sizeof(SERVICE_STATUS));
+
+ lpStatus->dwProcessId = lpService->ProcessId; /* FIXME */
+ lpStatus->dwServiceFlags = 0; /* FIXME */
+
+ return ERROR_SUCCESS;
+}
+
+
+/* Function 41 */
+DWORD REnumServicesStatusExA(
+ SC_RPC_HANDLE hSCManager,
+ SC_ENUM_TYPE InfoLevel,
+ DWORD dwServiceType,
+ DWORD dwServiceState,
+ LPBYTE lpBuffer,
+ DWORD cbBufSize,
+ LPBOUNDED_DWORD_256K pcbBytesNeeded,
+ LPBOUNDED_DWORD_256K lpServicesReturned,
+ LPBOUNDED_DWORD_256K lpResumeIndex,
+ LPCSTR pszGroupName)
+{
+ LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtrW = NULL;
+ LPENUM_SERVICE_STATUS_PROCESSA lpStatusPtrA = NULL;
+ LPWSTR lpStringPtrW;
+ LPSTR lpStringPtrA;
+ LPWSTR pszGroupNameW = NULL;
+ DWORD dwError;
+ DWORD dwServiceCount;
+
+ DPRINT("REnumServicesStatusExA() called\n");
+
+ if (pszGroupName)
+ {
+ pszGroupNameW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (strlen(pszGroupName) + 1) * sizeof(WCHAR));
+ if (!pszGroupNameW)
+ {
+ DPRINT("Failed to allocate buffer!\n");
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+
+ MultiByteToWideChar(CP_ACP,
+ 0,
+ pszGroupName,
+ -1,
+ pszGroupNameW,
+ strlen(pszGroupName) + 1);
+ }
+
+ if ((cbBufSize > 0) && (lpBuffer))
+ {
+ lpStatusPtrW = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbBufSize);
+ if (!lpStatusPtrW)
+ {
+ DPRINT("Failed to allocate buffer!\n");
+ return ERROR_NOT_ENOUGH_MEMORY;
+ }
+ }
+
+ dwError = REnumServicesStatusExW(hSCManager,
+ InfoLevel,
+ dwServiceType,
+ dwServiceState,
+ (LPBYTE)lpStatusPtrW,
+ cbBufSize,
+ pcbBytesNeeded,
+ lpServicesReturned,
+ lpResumeIndex,
+ pszGroupNameW);
+
+ /* if no services were returned then we are Done */
+ if (*lpServicesReturned == 0)
+ goto Done;
+
+ lpStatusPtrA = (LPENUM_SERVICE_STATUS_PROCESSA)lpBuffer;
+ lpStringPtrA = (LPSTR)((ULONG_PTR)lpBuffer +
+ *lpServicesReturned * sizeof(ENUM_SERVICE_STATUS_PROCESSA));
+ lpStringPtrW = (LPWSTR)((ULONG_PTR)lpStatusPtrW +
+ *lpServicesReturned * sizeof(ENUM_SERVICE_STATUS_PROCESSW));
+
+ for (dwServiceCount = 0; dwServiceCount < *lpServicesReturned; dwServiceCount++)
+ {
+ /* Copy the service name */
+ WideCharToMultiByte(CP_ACP,
+ 0,
+ lpStringPtrW,
+ -1,
+ lpStringPtrA,
+ wcslen(lpStringPtrW),
+ 0,
+ 0);
+
+ lpStatusPtrA->lpServiceName = (LPSTR)((ULONG_PTR)lpStringPtrA - (ULONG_PTR)lpBuffer);
+ lpStringPtrA += wcslen(lpStringPtrW) + 1;
+ lpStringPtrW += wcslen(lpStringPtrW) + 1;
+
+ /* Copy the display name */
+ WideCharToMultiByte(CP_ACP,
+ 0,
+ lpStringPtrW,
+ -1,
+ lpStringPtrA,
+ wcslen(lpStringPtrW),
+ 0,
+ 0);
+
+ lpStatusPtrA->lpDisplayName = (LPSTR)((ULONG_PTR)lpStringPtrA - (ULONG_PTR)lpBuffer);
+ lpStringPtrA += wcslen(lpStringPtrW) + 1;
+ lpStringPtrW += wcslen(lpStringPtrW) + 1;
+
+ /* Copy the status information */
+ memcpy(&lpStatusPtrA->ServiceStatusProcess,
+ &lpStatusPtrW->ServiceStatusProcess,
+ sizeof(SERVICE_STATUS));
+
+ lpStatusPtrA->ServiceStatusProcess.dwProcessId = lpStatusPtrW->ServiceStatusProcess.dwProcessId; /* FIXME */
+ lpStatusPtrA->ServiceStatusProcess.dwServiceFlags = 0; /* FIXME */
+ lpStatusPtrA++;
+ }
+
+Done:;
+ if (pszGroupNameW)
+ HeapFree(GetProcessHeap(), 0, pszGroupNameW);
+
+ if (lpStatusPtrW)
+ HeapFree(GetProcessHeap(), 0, lpStatusPtrW);
+
+ DPRINT("REnumServicesStatusExA() done (Error %lu)\n", dwError);
+
+ return dwError;
+}
+
+
+/* Function 42 */
+DWORD REnumServicesStatusExW(
+ SC_RPC_HANDLE hSCManager,
+ SC_ENUM_TYPE InfoLevel,
+ DWORD dwServiceType,
+ DWORD dwServiceState,
+ LPBYTE lpBuffer,
+ DWORD cbBufSize,
+ LPBOUNDED_DWORD_256K pcbBytesNeeded,
+ LPBOUNDED_DWORD_256K lpServicesReturned,
+ LPBOUNDED_DWORD_256K lpResumeIndex,
+ LPCWSTR pszGroupName)
+{
+ PMANAGER_HANDLE hManager;
+ PSERVICE lpService;
+ DWORD dwError = ERROR_SUCCESS;
+ PLIST_ENTRY ServiceEntry;
+ PSERVICE CurrentService;
+ DWORD dwState;
+ DWORD dwRequiredSize;
+ DWORD dwServiceCount;
+ DWORD dwSize;
+ DWORD dwLastResumeCount = 0;
+ LPENUM_SERVICE_STATUS_PROCESSW lpStatusPtr;
+ LPWSTR lpStringPtr;
+
+ DPRINT("REnumServicesStatusExW() called\n");
+
+ if (ScmShutdown)
+ return ERROR_SHUTDOWN_IN_PROGRESS;
+
+ if (InfoLevel != SC_ENUM_PROCESS_INFO)
+ return ERROR_INVALID_LEVEL;
+
+ hManager = ScmGetServiceManagerFromHandle(hSCManager);
+ if (hManager == NULL)
+ {
+ DPRINT1("Invalid service manager handle!\n");
+ return ERROR_INVALID_HANDLE;
+ }
+
+ *pcbBytesNeeded = 0;
+ *lpServicesReturned = 0;
+
+ if ((dwServiceType!=SERVICE_DRIVER) && (dwServiceType!=SERVICE_WIN32))
+ {
+ DPRINT("Not a valid Service Type!\n");
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ if ((dwServiceState<SERVICE_ACTIVE) || (dwServiceState>SERVICE_STATE_ALL))
+ {
+ DPRINT("Not a valid Service State!\n");
+ return ERROR_INVALID_PARAMETER;
+ }
+
+ /* Check access rights */
+ if (!RtlAreAllAccessesGranted(hManager->Handle.DesiredAccess,
+ SC_MANAGER_ENUMERATE_SERVICE))
+ {
+ DPRINT("Insufficient access rights! 0x%lx\n",
+ hManager->Handle.DesiredAccess);
+ return ERROR_ACCESS_DENIED;
+ }
+
+ if (lpResumeIndex) dwLastResumeCount = *lpResumeIndex;
+
+ /* Lock the service list shared */
+
+ lpService = ScmGetServiceEntryByResumeCount(dwLastResumeCount);
+ if (lpService == NULL)
+ {
+ dwError = ERROR_SUCCESS;
+ goto Done;
+ }
+
+ dwRequiredSize = 0;
+ dwServiceCount = 0;
+
+ for (ServiceEntry = &lpService->ServiceListEntry;
+ ServiceEntry != &ServiceListHead;
+ ServiceEntry = ServiceEntry->Flink)
+ {
+ CurrentService = CONTAINING_RECORD(ServiceEntry,
+ SERVICE,
+ ServiceListEntry);
+
+ if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
+ continue;
+
+ dwState = SERVICE_ACTIVE;
+ if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
+ dwState = SERVICE_INACTIVE;
+
+ if ((dwState & dwServiceState) == 0)
+ continue;
+
+ if (pszGroupName)
+ {
+ if (*pszGroupName == 0)
+ {
+ if (CurrentService->lpGroup != NULL)
+ continue;
+ }
+ else
+ {
+ if ((CurrentService->lpGroup == NULL) ||
+ _wcsicmp(pszGroupName, CurrentService->lpGroup->lpGroupName))
+ continue;
+ }
+ }
+
+ dwSize = sizeof(ENUM_SERVICE_STATUS_PROCESSW) +
+ ((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
+ ((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
+
+ if (dwRequiredSize + dwSize <= cbBufSize)
+ {
+ DPRINT("Service name: %S fit\n", CurrentService->lpServiceName);
+ dwRequiredSize += dwSize;
+ dwServiceCount++;
+ dwLastResumeCount = CurrentService->dwResumeCount;
+ }
+ else
+ {
+ DPRINT("Service name: %S no fit\n", CurrentService->lpServiceName);
+ break;
+ }
+
+ }
+
+ DPRINT("dwRequiredSize: %lu\n", dwRequiredSize);
+ DPRINT("dwServiceCount: %lu\n", dwServiceCount);
+
+ for (;
+ ServiceEntry != &ServiceListHead;
+ ServiceEntry = ServiceEntry->Flink)
+ {
+ CurrentService = CONTAINING_RECORD(ServiceEntry,
+ SERVICE,
+ ServiceListEntry);
+
+ if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
+ continue;
+
+ dwState = SERVICE_ACTIVE;
+ if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
+ dwState = SERVICE_INACTIVE;
+
+ if ((dwState & dwServiceState) == 0)
+ continue;
+
+ if (pszGroupName)
+ {
+ if (*pszGroupName == 0)
+ {
+ if (CurrentService->lpGroup != NULL)
+ continue;
+ }
+ else
+ {
+ if ((CurrentService->lpGroup == NULL) ||
+ _wcsicmp(pszGroupName, CurrentService->lpGroup->lpGroupName))
+ continue;
+ }
+ }
+
+ dwRequiredSize += (sizeof(ENUM_SERVICE_STATUS_PROCESSW) +
+ ((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
+ ((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR)));
+
+ dwError = ERROR_MORE_DATA;
+ }
+
+ DPRINT("*pcbBytesNeeded: %lu\n", dwRequiredSize);
+
+ if (lpResumeIndex)
+ *lpResumeIndex = dwLastResumeCount;
+
+ *lpServicesReturned = dwServiceCount;
+ *pcbBytesNeeded = dwRequiredSize;
+
+ /* If there was no services that matched */
+ if ((!dwServiceCount) && (dwError != ERROR_MORE_DATA))
+ {
+ dwError = ERROR_SERVICE_DOES_NOT_EXIST;
+ goto Done;
+ }
+
+ lpStatusPtr = (LPENUM_SERVICE_STATUS_PROCESSW)lpBuffer;
+ lpStringPtr = (LPWSTR)((ULONG_PTR)lpBuffer +
+ dwServiceCount * sizeof(ENUM_SERVICE_STATUS_PROCESSW));
+
+ dwRequiredSize = 0;
+ for (ServiceEntry = &lpService->ServiceListEntry;
+ ServiceEntry != &ServiceListHead;
+ ServiceEntry = ServiceEntry->Flink)
+ {
+ CurrentService = CONTAINING_RECORD(ServiceEntry,
+ SERVICE,
+ ServiceListEntry);
+
+ if ((CurrentService->Status.dwServiceType & dwServiceType) == 0)
+ continue;
+
+ dwState = SERVICE_ACTIVE;
+ if (CurrentService->Status.dwCurrentState == SERVICE_STOPPED)
+ dwState = SERVICE_INACTIVE;
+
+ if ((dwState & dwServiceState) == 0)
+ continue;
+
+ if (pszGroupName)
+ {
+ if (*pszGroupName == 0)
+ {
+ if (CurrentService->lpGroup != NULL)
+ continue;
+ }
+ else
+ {
+ if ((CurrentService->lpGroup == NULL) ||
+ _wcsicmp(pszGroupName, CurrentService->lpGroup->lpGroupName))
+ continue;
+ }
+ }
+
+ dwSize = sizeof(ENUM_SERVICE_STATUS_PROCESSW) +
+ ((wcslen(CurrentService->lpServiceName) + 1) * sizeof(WCHAR)) +
+ ((wcslen(CurrentService->lpDisplayName) + 1) * sizeof(WCHAR));
+
+ if (dwRequiredSize + dwSize <= cbBufSize)
+ {
+ /* Copy the service name */
+ wcscpy(lpStringPtr,
+ CurrentService->lpServiceName);
+ lpStatusPtr->lpServiceName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpBuffer);
+ lpStringPtr += (wcslen(CurrentService->lpServiceName) + 1);
+
+ /* Copy the display name */
+ wcscpy(lpStringPtr,
+ CurrentService->lpDisplayName);
+ lpStatusPtr->lpDisplayName = (LPWSTR)((ULONG_PTR)lpStringPtr - (ULONG_PTR)lpBuffer);
+ lpStringPtr += (wcslen(CurrentService->lpDisplayName) + 1);
+
+ /* Copy the status information */
+ memcpy(&lpStatusPtr->ServiceStatusProcess,
+ &CurrentService->Status,
+ sizeof(SERVICE_STATUS));
+ lpStatusPtr->ServiceStatusProcess.dwProcessId = CurrentService->ProcessId; /* FIXME */
+ lpStatusPtr->ServiceStatusProcess.dwServiceFlags = 0; /* FIXME */
+
+ lpStatusPtr++;
+ dwRequiredSize += dwSize;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (dwError == 0)
+ {
+ *pcbBytesNeeded = 0;
+ if (lpResumeIndex)
+ *lpResumeIndex = 0;
+ }
+
+Done:;
+ /* Unlock the service list */
+
+ DPRINT("REnumServicesStatusExW() done (Error %lu)\n", dwError);
+
+ return dwError;
+}
+
+
+/* Function 43 */
+DWORD RSendTSMessage(
+ handle_t BindingHandle) /* FIXME */
+{
+ UNIMPLEMENTED;
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 44 */
+DWORD RCreateServiceWOW64A(
+ handle_t BindingHandle,
+ LPSTR lpServiceName,
+ LPSTR lpDisplayName,
+ DWORD dwDesiredAccess,
+ DWORD dwServiceType,
+ DWORD dwStartType,
+ DWORD dwErrorControl,
+ LPSTR lpBinaryPathName,
+ LPSTR lpLoadOrderGroup,
+ LPDWORD lpdwTagId,
+ LPBYTE lpDependencies,
+ DWORD dwDependSize,
+ LPSTR lpServiceStartName,
+ LPBYTE lpPassword,
+ DWORD dwPwSize,
+ LPSC_RPC_HANDLE lpServiceHandle)
+{
+ UNIMPLEMENTED;
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 45 */
+DWORD RCreateServiceWOW64W(
+ handle_t BindingHandle,
+ LPWSTR lpServiceName,
+ LPWSTR lpDisplayName,
+ DWORD dwDesiredAccess,
+ DWORD dwServiceType,
+ DWORD dwStartType,
+ DWORD dwErrorControl,
+ LPWSTR lpBinaryPathName,
+ LPWSTR lpLoadOrderGroup,
+ LPDWORD lpdwTagId,
+ LPBYTE lpDependencies,
+ DWORD dwDependSize,
+ LPWSTR lpServiceStartName,
+ LPBYTE lpPassword,
+ DWORD dwPwSize,
+ LPSC_RPC_HANDLE lpServiceHandle)
+{
+ UNIMPLEMENTED;
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 46 */
+DWORD RQueryServiceTagInfo(
+ handle_t BindingHandle) /* FIXME */
+{
+ UNIMPLEMENTED;
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 47 */
+DWORD RNotifyServiceStatusChange(
+ SC_RPC_HANDLE hService,
+ SC_RPC_NOTIFY_PARAMS NotifyParams,
+ GUID *pClientProcessGuid,
+ GUID *pSCMProcessGuid,
+ PBOOL pfCreateRemoteQueue,
+ LPSC_NOTIFY_RPC_HANDLE phNotify)
+{
+ UNIMPLEMENTED;
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 48 */
+DWORD RGetNotifyResults(
+ SC_NOTIFY_RPC_HANDLE hNotify,
+ PSC_RPC_NOTIFY_PARAMS_LIST *ppNotifyParams)
+{
+ UNIMPLEMENTED;
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 49 */
+DWORD RCloseNotifyHandle(
+ LPSC_NOTIFY_RPC_HANDLE phNotify,
+ PBOOL pfApcFired)
+{
+ UNIMPLEMENTED;
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 50 */
+DWORD RControlServiceExA(
+ SC_RPC_HANDLE hService,
+ DWORD dwControl,
+ DWORD dwInfoLevel)
+{
+ UNIMPLEMENTED;
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 51 */
+DWORD RControlServiceExW(
+ SC_RPC_HANDLE hService,
+ DWORD dwControl,
+ DWORD dwInfoLevel)
+{
+ UNIMPLEMENTED;
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 52 */
+DWORD RSendPnPMessage(
+ handle_t BindingHandle) /* FIXME */
+{
+ UNIMPLEMENTED;
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 53 */
+DWORD RValidatePnPService(
+ handle_t BindingHandle) /* FIXME */
+{
+ UNIMPLEMENTED;
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 54 */
+DWORD ROpenServiceStatusHandle(
+ handle_t BindingHandle) /* FIXME */
+{
+ UNIMPLEMENTED;
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+/* Function 55 */
+DWORD RFunction55(
+ handle_t BindingHandle) /* FIXME */
+{
+ UNIMPLEMENTED;
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+
+void __RPC_FAR * __RPC_USER midl_user_allocate(size_t len)
+{
+ return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len);
+}
+
+
+void __RPC_USER midl_user_free(void __RPC_FAR * ptr)
+{
+ HeapFree(GetProcessHeap(), 0, ptr);
+}
+
+
+void __RPC_USER SC_RPC_HANDLE_rundown(SC_RPC_HANDLE hSCObject)
+{
+}
+
+
+void __RPC_USER SC_RPC_LOCK_rundown(SC_RPC_LOCK Lock)
+{
+}
+
+
+void __RPC_USER SC_NOTIFY_RPC_HANDLE_rundown(SC_NOTIFY_RPC_HANDLE hNotify)
+{
+}
+
+/* EOF */
--- /dev/null
- freeldr/freeldr/windows/headless.c
+
+CreateBootSectorTarget(dosmbr ${CMAKE_CURRENT_SOURCE_DIR}/freeldr/bootsect/dosmbr.asm ${CMAKE_CURRENT_BINARY_DIR}/freeldr/bootsect/dosmbr.bin)
+CreateBootSectorTarget(ext2 ${CMAKE_CURRENT_SOURCE_DIR}/freeldr/bootsect/ext2.asm ${CMAKE_CURRENT_BINARY_DIR}/freeldr/bootsect/ext2.bin)
+CreateBootSectorTarget(fat32 ${CMAKE_CURRENT_SOURCE_DIR}/freeldr/bootsect/fat32.asm ${CMAKE_CURRENT_BINARY_DIR}/freeldr/bootsect/fat32.bin)
+CreateBootSectorTarget(fat ${CMAKE_CURRENT_SOURCE_DIR}/freeldr/bootsect/fat.asm ${CMAKE_CURRENT_BINARY_DIR}/freeldr/bootsect/fat.bin)
+CreateBootSectorTarget(isoboot ${CMAKE_CURRENT_SOURCE_DIR}/freeldr/bootsect/isoboot.asm ${CMAKE_CURRENT_BINARY_DIR}/freeldr/bootsect/isoboot.bin)
+CreateBootSectorTarget(isobtrt ${CMAKE_CURRENT_SOURCE_DIR}/freeldr/bootsect/isobtrt.asm ${CMAKE_CURRENT_BINARY_DIR}/freeldr/bootsect/isobtrt.bin)
+
+include_directories(BEFORE freeldr/freeldr/include)
+include_directories(${REACTOS_SOURCE_DIR}/ntoskrnl/include)
+
++if(ARCH MATCHES arm)
++ if(SARCH MATCHES omap-zoom2)
++ add_definitions(-D_ZOOM2_)
++ endif()
++endif()
++
+if(ARCH MATCHES i386)
+if(MSVC)
+list(APPEND FREELDR_BASE64K_SOURCE
+ freeldr/freeldr/arch/i386/realmode.S)
+else()
+list(APPEND FREELDR_STARTUP_SOURCE
+ freeldr/freeldr/arch/i386/fathelp.S
+ freeldr/freeldr/arch/i386/arch.S)
+endif()
+elseif(ARCH MATCHES amd64)
+list(APPEND FREELDR_STARTUP_SOURCE
+ freeldr/freeldr/arch/i386/fathelp.S
+ freeldr/freeldr/arch/amd64/arch.S)
+endif(ARCH MATCHES i386)
+
+if(ARCH MATCHES i386)
+if(NOT MSVC)
+list(APPEND FREELDR_BASE64K_SOURCE
+ freeldr/freeldr/arch/i386/boot.S
+ freeldr/freeldr/arch/i386/drvmap.S
+ freeldr/freeldr/arch/i386/i386cpu.S
+ freeldr/freeldr/arch/i386/i386idt.S
+ freeldr/freeldr/arch/i386/i386pnp.S
+ freeldr/freeldr/arch/i386/i386trap.S
+ freeldr/freeldr/arch/i386/int386.S
+ freeldr/freeldr/arch/i386/linux.S
+ freeldr/freeldr/arch/i386/mb.S
+ freeldr/freeldr/arch/i386/i386bug.c)
+endif()
+elseif(ARCH MATCHES amd64)
+list(APPEND FREELDR_BASE64K_SOURCE
+ freeldr/freeldr/arch/i386/drvmap.S
+ freeldr/freeldr/arch/i386/i386cpu.S
+ freeldr/freeldr/arch/i386/i386idt.S
+ freeldr/freeldr/arch/i386/i386trap.S
+ freeldr/freeldr/arch/amd64/mb.S)
+endif(ARCH MATCHES i386)
+
+set_source_files_properties(${FREELDR_BASE64K_SOURCE} PROPERTIES COMPILE_DEFINITIONS "_NTHAL_")
+
+include_directories(${REACTOS_SOURCE_DIR}/lib/cmlib)
+
+list(APPEND FREELDR_BASE_SOURCE
+ freeldr/freeldr/arcemul/mm.c
+ freeldr/freeldr/arcemul/time.c
+ freeldr/freeldr/cache/blocklist.c
+ freeldr/freeldr/cache/cache.c
+ freeldr/freeldr/comm/rs232.c
+ freeldr/freeldr/disk/disk.c
+ freeldr/freeldr/disk/partition.c
+ freeldr/freeldr/disk/ramdisk.c
+ freeldr/freeldr/disk/scsiport.c
+ freeldr/freeldr/fs/ext2.c
+ freeldr/freeldr/fs/fat.c
+ freeldr/freeldr/fs/fs.c
+ freeldr/freeldr/fs/iso.c
+ freeldr/freeldr/fs/ntfs.c
+ freeldr/freeldr/inifile/ini_init.c
+ freeldr/freeldr/inifile/inifile.c
+ freeldr/freeldr/inifile/parse.c
+ freeldr/freeldr/mm/meminit.c
+ freeldr/freeldr/mm/mm.c
+ freeldr/freeldr/reactos/registry.c
+ freeldr/freeldr/reactos/arcname.c
+ freeldr/freeldr/reactos/archwsup.c
+ freeldr/freeldr/reactos/binhive.c
+ freeldr/freeldr/reactos/reactos.c
+ freeldr/freeldr/reactos/imageldr.c
+ freeldr/freeldr/rtl/bget.c
+ freeldr/freeldr/rtl/libsupp.c
+ freeldr/freeldr/ui/directui.c
+ freeldr/freeldr/ui/gui.c
+ freeldr/freeldr/ui/minitui.c
+ freeldr/freeldr/ui/noui.c
+ freeldr/freeldr/ui/tui.c
+ freeldr/freeldr/ui/tuimenu.c
+ freeldr/freeldr/ui/ui.c
+ freeldr/freeldr/video/fade.c
+ freeldr/freeldr/video/palette.c
+ freeldr/freeldr/video/video.c
+ freeldr/freeldr/windows/conversion.c
- list(APPEND FREELDR_BASE_SOURCE freeldr/freeldr/disk/scsiport.c)
+ freeldr/freeldr/windows/peloader.c
+ freeldr/freeldr/windows/winldr.c
+ freeldr/freeldr/windows/wlmemory.c
+ freeldr/freeldr/windows/wlregistry.c
+ freeldr/freeldr/freeldr.c
+ freeldr/freeldr/debug.c
+ freeldr/freeldr/version.c
+ freeldr/freeldr/cmdline.c
+ freeldr/freeldr/machine.c
+ freeldr/freeldr/options.c
+ freeldr/freeldr/linuxboot.c
+ freeldr/freeldr/oslist.c)
+
+if(ARCH MATCHES i386)
++list(APPEND FREELDR_BASE_SOURCE
++ freeldr/freeldr/windows/headless.c
++ freeldr/freeldr/disk/scsiport.c)
+endif(ARCH MATCHES i386)
+
+set_source_files_properties(${FREELDR_BASE_SOURCE} PROPERTIES COMPILE_DEFINITIONS "_NTHAL_;_BLDR_;_NTSYSTEM_")
+
+include_directories(${REACTOS_SOURCE_DIR}/include/reactos/libs)
+include_directories(${REACTOS_SOURCE_DIR}/include/reactos/elf)
+
+if(ARCH MATCHES i386)
+list(APPEND FREELDR_ARCH_SOURCE
+ freeldr/freeldr/arch/i386/archmach.c
+ freeldr/freeldr/arch/i386/custom.c
+ freeldr/freeldr/arch/i386/drivemap.c
+ freeldr/freeldr/arch/i386/halstub.c
+ freeldr/freeldr/arch/i386/hardware.c
+ freeldr/freeldr/arch/i386/hwacpi.c
+ freeldr/freeldr/arch/i386/hwapm.c
+ freeldr/freeldr/arch/i386/hwpci.c
+ freeldr/freeldr/arch/i386/i386disk.c
+ freeldr/freeldr/arch/i386/i386rtl.c
+ freeldr/freeldr/arch/i386/i386vid.c
+ freeldr/freeldr/arch/i386/loader.c
+ freeldr/freeldr/arch/i386/machpc.c
+ freeldr/freeldr/arch/i386/miscboot.c
+ freeldr/freeldr/arch/i386/ntoskrnl.c
+ freeldr/freeldr/arch/i386/pccons.c
+ freeldr/freeldr/arch/i386/pcdisk.c
+ freeldr/freeldr/arch/i386/pcmem.c
+ freeldr/freeldr/arch/i386/pcrtc.c
+ freeldr/freeldr/arch/i386/pcvideo.c
+ freeldr/freeldr/arch/i386/machxbox.c
+ freeldr/freeldr/arch/i386/xboxcons.c
+ freeldr/freeldr/arch/i386/xboxdisk.c
+ freeldr/freeldr/arch/i386/xboxfont.c
+ freeldr/freeldr/arch/i386/xboxhw.c
+ freeldr/freeldr/arch/i386/xboxi2c.c
+ freeldr/freeldr/arch/i386/xboxmem.c
+ freeldr/freeldr/arch/i386/xboxrtc.c
+ freeldr/freeldr/arch/i386/xboxvideo.c
+ freeldr/freeldr/windows/i386/ntsetup.c
+ freeldr/freeldr/windows/i386/wlmemory.c)
+else()
+#TBD
+endif(ARCH MATCHES i386)
+
+set_source_files_properties(${FREELDR_ARCH_SOURCE} PROPERTIES COMPILE_DEFINITIONS "_NTHAL_;_BLDR_;_NTSYSTEM_")
+
+list(APPEND SETUPLDR_MAIN_SOURCE
+ freeldr/freeldr/bootmgr.c
+ freeldr/freeldr/inffile/inffile.c
+ freeldr/freeldr/reactos/setupldr.c)
+
+if(ARCH MATCHES i386)
+list(APPEND SETUPLDR_MAIN_SOURCE freeldr/freeldr/windows/setupldr2.c)
+elseif(ARCH MATCHES amd64)
+list(APPEND SETUPLDR_MAIN_SOURCE freeldr/freeldr/windows/setupldr2.c)
+endif(ARCH MATCHES i386)
+
+set_source_files_properties(${SETUPLDR_MAIN_SOURCE} PROPERTIES COMPILE_FLAGS "-ffreestanding -fno-builtin -fno-inline -fno-zero-initialized-in-bss")
+
+
+
+list(APPEND FREELDR_SOURCE
+ freeldr/freeldr/bootmgr.c
+ ${FREELDR_STARTUP_SOURCE}
+ ${FREELDR_BASE64K_SOURCE}
+ ${FREELDR_BASE_SOURCE}
+ ${FREELDR_ARCH_SOURCE})
+
+add_library(freeldr SHARED
+ ${CMAKE_CURRENT_BINARY_DIR}/freeldr_freeldr.h.gch
+ ${FREELDR_SOURCE})
+
+if(NOT MSVC)
+set_target_properties(freeldr PROPERTIES LINK_FLAGS "-Wl,--strip-all -Wl,--exclude-all-symbols -Wl,--file-alignment,0x1000 -Wl,-T,${CMAKE_CURRENT_SOURCE_DIR}/freeldr/freeldr/freeldr_i386.lnk" SUFFIX ".sys")
+set_image_base(freeldr 0x8000)
+else()
+set_target_properties(freeldr PROPERTIES LINK_FLAGS "/DRIVER /FIXED /ALIGN:0x400 /SECTION:.text,ERW /SECTION:.data,RW /MERGE:.text16=.text /MERGE:.data=.text /MERGE:.rdata=.text /MERGE:.bss=.text /SUBSYSTEM:BOOT_APPLICATION" SUFFIX ".sys")
+set_image_base(freeldr 0x10000)
+endif()
+
+set_subsystem(freeldr native)
+set_entrypoint(freeldr mainCRTStartup)
+
+if(ARCH MATCHES i386)
+target_link_libraries(freeldr mini_hal)
+endif(ARCH MATCHES i386)
+
+target_link_libraries(freeldr
+ cportlib
+ rossym
+ cmlib
+ rtl
+ libcntpr)
+add_pch(freeldr ${CMAKE_CURRENT_SOURCE_DIR}/freeldr/freeldr/include/freeldr.h ${FREELDR_SOURCE})
+add_dependencies(freeldr asm)
+
+list(APPEND SETUPLDR_SOURCE
+ ${FREELDR_STARTUP_SOURCE}
+ ${FREELDR_BASE64K_SOURCE}
+ ${FREELDR_BASE_SOURCE}
+ ${FREELDR_ARCH_SOURCE}
+ ${SETUPLDR_MAIN_SOURCE})
+
+add_library(setupldr SHARED ${SETUPLDR_SOURCE})
+
+if(NOT MSVC)
+set_target_properties(setupldr PROPERTIES LINK_FLAGS "-Wl,--strip-all -Wl,--exclude-all-symbols -Wl,--file-alignment,0x1000 -Wl,-T,${CMAKE_CURRENT_SOURCE_DIR}/freeldr/freeldr/freeldr_i386.lnk" SUFFIX ".sys" COMPILE_DEFINITIONS "FREELDR_REACTOS_SETUP")
+set_image_base(setupldr 0x8000)
+else()
+set_target_properties(setupldr PROPERTIES LINK_FLAGS "/SECTION:.text,ERWP,ALIGN=0x1000" SUFFIX ".sys" COMPILE_DEFINITIONS "FREELDR_REACTOS_SETUP")
+endif()
+
+set_subsystem(setupldr native)
+set_entrypoint(setupldr mainCRTStartup)
+
+if(ARCH MATCHES i386)
+target_link_libraries(setupldr mini_hal)
+endif(ARCH MATCHES i386)
+
+target_link_libraries(setupldr
+ cportlib
+ rossym
+ cmlib
+ rtl
+ libcntpr)
+
+add_dependencies(setupldr asm)
+
+# Bootcd files
+add_minicd_target(setupldr loader setupldr.sys)
+add_minicd_target(freeldr loader freeldr.sys)
+add_minicd(${CMAKE_CURRENT_SOURCE_DIR}/bootdata/txtsetup.sif reactos txtsetup.sif)
+add_minicd(${CMAKE_CURRENT_SOURCE_DIR}/bootdata/bootcd.ini "" freeldr.ini)
+add_minicd(${CMAKE_CURRENT_SOURCE_DIR}/bootdata/hivecls_${ARCH}.inf reactos hivecls.inf)
+add_minicd(${CMAKE_CURRENT_SOURCE_DIR}/bootdata/hivedef_${ARCH}.inf reactos hivedef.inf)
+add_minicd(${CMAKE_CURRENT_SOURCE_DIR}/bootdata/hivesft_${ARCH}.inf reactos hivesft.inf)
+add_minicd(${CMAKE_CURRENT_SOURCE_DIR}/bootdata/hivesys_${ARCH}.inf reactos hivesys.inf)
+add_minicd(${CMAKE_CURRENT_SOURCE_DIR}/bootdata/autorun.inf "" autorun.inf)
+add_minicd(${CMAKE_CURRENT_SOURCE_DIR}/bootdata/icon.ico "" icon.ico)
+add_minicd(${CMAKE_CURRENT_SOURCE_DIR}/bootdata/readme.txt "" readme.txt)
+# Livecd files
+list(APPEND LIVECD_HIVES
+ ${CMAKE_CURRENT_SOURCE_DIR}/bootdata/livecd.inf
+ ${CMAKE_CURRENT_SOURCE_DIR}/bootdata/hiveinst_${ARCH}.inf)
+
+add_custom_command(
+ OUTPUT ${LIVECD_DIR}/reactos/system32/config/sam
+ COMMAND native-mkhive ${CMAKE_CURRENT_SOURCE_DIR}/bootdata ${LIVECD_DIR}/reactos/system32/config ${ARCH} ${LIVECD_HIVES}
+ DEPENDS native-mkhive)
+
+add_custom_target(livecd_hives DEPENDS ${LIVECD_DIR}/reactos/system32/config/sam)
+
+add_livecd_target(setupldr loader)
+add_livecd(${REACTOS_SOURCE_DIR}/boot/bootdata/livecd.ini "" freeldr.ini)
--- /dev/null
-
+/*
+ * FreeLoader
+ *
+ * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
+ * Copyright (C) 2006 Aleksey Bragin <aleksey@reactos.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <freeldr.h>
+
+#include <ndk/ldrtypes.h>
+#include <debug.h>
+
+// TODO: Move to .h
+void WinLdrSetupForNt(PLOADER_PARAMETER_BLOCK LoaderBlock,
+ PVOID *GdtIdt,
+ ULONG *PcrBasePage,
+ ULONG *TssBasePage);
+
+//FIXME: Do a better way to retrieve Arc disk information
+extern ULONG reactos_disk_count;
+extern ARC_DISK_SIGNATURE reactos_arc_disk_info[];
+extern char reactos_arc_strings[32][256];
+
+extern BOOLEAN UseRealHeap;
+extern ULONG LoaderPagesSpanned;
+extern BOOLEAN AcpiPresent;
+
+extern HEADLESS_LOADER_BLOCK LoaderRedirectionInformation;
+extern BOOLEAN WinLdrTerminalConnected;
+
+extern void WinLdrSetupEms(IN PCHAR BootOptions);
+
+BOOLEAN
+WinLdrCheckForLoadedDll(IN OUT PLOADER_PARAMETER_BLOCK WinLdrBlock,
+ IN PCH DllName,
+ OUT PLDR_DATA_TABLE_ENTRY *LoadedEntry);
+
+// debug stuff
+VOID DumpMemoryAllocMap(VOID);
+VOID WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock);
+VOID WinLdrpDumpBootDriver(PLOADER_PARAMETER_BLOCK LoaderBlock);
+VOID WinLdrpDumpArcDisks(PLOADER_PARAMETER_BLOCK LoaderBlock);
+
+
+// Init "phase 0"
+VOID
+AllocateAndInitLPB(PLOADER_PARAMETER_BLOCK *OutLoaderBlock)
+{
+ PLOADER_PARAMETER_BLOCK LoaderBlock;
+
+ /* Allocate and zero-init the LPB */
+ LoaderBlock = MmHeapAlloc(sizeof(LOADER_PARAMETER_BLOCK));
+ RtlZeroMemory(LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
+
+ /* Init three critical lists, used right away */
+ InitializeListHead(&LoaderBlock->LoadOrderListHead);
+ InitializeListHead(&LoaderBlock->MemoryDescriptorListHead);
+ InitializeListHead(&LoaderBlock->BootDriverListHead);
+
+ /* Alloc space for NLS (it will be converted to VA in WinLdrLoadNLS) */
+ LoaderBlock->NlsData = MmHeapAlloc(sizeof(NLS_DATA_BLOCK));
+ if (LoaderBlock->NlsData == NULL)
+ {
+ UiMessageBox("Failed to allocate memory for NLS table data!");
+ return;
+ }
+ RtlZeroMemory(LoaderBlock->NlsData, sizeof(NLS_DATA_BLOCK));
+
+ *OutLoaderBlock = LoaderBlock;
+}
+
+// Init "phase 1"
+VOID
+WinLdrInitializePhase1(PLOADER_PARAMETER_BLOCK LoaderBlock,
+ PCHAR Options,
+ PCHAR SystemRoot,
+ PCHAR BootPath,
+ USHORT VersionToBoot)
+{
+ /* Examples of correct options and paths */
+ //CHAR Options[] = "/DEBUGPORT=COM1 /BAUDRATE=115200";
+ //CHAR Options[] = "/NODEBUG";
+ //CHAR SystemRoot[] = "\\WINNT\\";
+ //CHAR ArcBoot[] = "multi(0)disk(0)rdisk(0)partition(1)";
+
+ CHAR HalPath[] = "\\";
+ CHAR ArcBoot[256];
+ CHAR MiscFiles[256];
+ ULONG i, PathSeparator;
+ PLOADER_PARAMETER_EXTENSION Extension;
+
+ /* Construct SystemRoot and ArcBoot from SystemPath */
+ PathSeparator = strstr(BootPath, "\\") - BootPath;
+ strncpy(ArcBoot, BootPath, PathSeparator);
+ ArcBoot[PathSeparator] = 0;
+
+ DPRINTM(DPRINT_WINDOWS, "ArcBoot: %s\n", ArcBoot);
+ DPRINTM(DPRINT_WINDOWS, "SystemRoot: %s\n", SystemRoot);
+ DPRINTM(DPRINT_WINDOWS, "Options: %s\n", Options);
+
+ /* Fill Arc BootDevice */
+ LoaderBlock->ArcBootDeviceName = MmHeapAlloc(strlen(ArcBoot)+1);
+ strcpy(LoaderBlock->ArcBootDeviceName, ArcBoot);
+ LoaderBlock->ArcBootDeviceName = PaToVa(LoaderBlock->ArcBootDeviceName);
+
+ /* Fill Arc HalDevice, it matches ArcBoot path */
+ LoaderBlock->ArcHalDeviceName = MmHeapAlloc(strlen(ArcBoot)+1);
+ strcpy(LoaderBlock->ArcHalDeviceName, ArcBoot);
+ LoaderBlock->ArcHalDeviceName = PaToVa(LoaderBlock->ArcHalDeviceName);
+
+ /* Fill SystemRoot */
+ LoaderBlock->NtBootPathName = MmHeapAlloc(strlen(SystemRoot)+1);
+ strcpy(LoaderBlock->NtBootPathName, SystemRoot);
+ LoaderBlock->NtBootPathName = PaToVa(LoaderBlock->NtBootPathName);
+
+ /* Fill NtHalPathName */
+ LoaderBlock->NtHalPathName = MmHeapAlloc(strlen(HalPath)+1);
+ strcpy(LoaderBlock->NtHalPathName, HalPath);
+ LoaderBlock->NtHalPathName = PaToVa(LoaderBlock->NtHalPathName);
+
+ /* Fill load options */
+ LoaderBlock->LoadOptions = MmHeapAlloc(strlen(Options)+1);
+ strcpy(LoaderBlock->LoadOptions, Options);
+ LoaderBlock->LoadOptions = PaToVa(LoaderBlock->LoadOptions);
+
+ /* Arc devices */
+ LoaderBlock->ArcDiskInformation = (PARC_DISK_INFORMATION)MmHeapAlloc(sizeof(ARC_DISK_INFORMATION));
+ InitializeListHead(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);
+
+ /* Convert ARC disk information from freeldr to a correct format */
+ for (i = 0; i < reactos_disk_count; i++)
+ {
+ PARC_DISK_SIGNATURE ArcDiskInfo;
+
+ /* Get the ARC structure */
+ ArcDiskInfo = (PARC_DISK_SIGNATURE)MmHeapAlloc(sizeof(ARC_DISK_SIGNATURE));
+ RtlZeroMemory(ArcDiskInfo, sizeof(ARC_DISK_SIGNATURE));
+
+ /* Copy the data over */
+ ArcDiskInfo->Signature = reactos_arc_disk_info[i].Signature;
+ ArcDiskInfo->CheckSum = reactos_arc_disk_info[i].CheckSum;
+
+ /* Copy the ARC Name */
+ ArcDiskInfo->ArcName = (PCHAR)MmHeapAlloc(sizeof(CHAR)*256);
+ strcpy(ArcDiskInfo->ArcName, reactos_arc_disk_info[i].ArcName);
+ ArcDiskInfo->ArcName = (PCHAR)PaToVa(ArcDiskInfo->ArcName);
+
+ /* Mark partition table as valid */
+ ArcDiskInfo->ValidPartitionTable = TRUE;
+
+ /* Insert into the list */
+ InsertTailList(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead,
+ &ArcDiskInfo->ListEntry);
+ }
+
+ /* Convert all list's to Virtual address */
+
+ /* Convert the ArcDisks list to virtual address */
+ List_PaToVa(&LoaderBlock->ArcDiskInformation->DiskSignatureListHead);
+ LoaderBlock->ArcDiskInformation = PaToVa(LoaderBlock->ArcDiskInformation);
+
+ /* Convert configuration entries to VA */
+ ConvertConfigToVA(LoaderBlock->ConfigurationRoot);
+ LoaderBlock->ConfigurationRoot = PaToVa(LoaderBlock->ConfigurationRoot);
+
+ /* Convert all DTE into virtual addresses */
+ List_PaToVa(&LoaderBlock->LoadOrderListHead);
+
+ /* this one will be converted right before switching to
+ virtual paging mode */
+ //List_PaToVa(&LoaderBlock->MemoryDescriptorListHead);
+
+ /* Convert list of boot drivers */
+ List_PaToVa(&LoaderBlock->BootDriverListHead);
+
+ /* Initialize Extension now */
+ Extension = MmHeapAlloc(sizeof(LOADER_PARAMETER_EXTENSION));
+ if (Extension == NULL)
+ {
+ UiMessageBox("Failed to allocate LPB Extension!");
+ return;
+ }
+ RtlZeroMemory(Extension, sizeof(LOADER_PARAMETER_EXTENSION));
+
+ /* Fill LPB extension */
+ Extension->Size = sizeof(LOADER_PARAMETER_EXTENSION);
+ Extension->MajorVersion = (VersionToBoot & 0xFF00) >> 8;
+ Extension->MinorVersion = VersionToBoot & 0xFF;
+ Extension->Profile.Status = 2;
+
+ /* Check if ACPI is present */
+ if (AcpiPresent)
+ {
+ /* See KiRosFrldrLpbToNtLpb for details */
+ Extension->AcpiTable = (PVOID)1;
+ }
+
++#ifndef _M_ARM
+ /* Set headless block pointer */
+ if (WinLdrTerminalConnected)
+ {
+ Extension->HeadlessLoaderBlock = MmHeapAlloc(sizeof(HEADLESS_LOADER_BLOCK));
+ if (Extension->HeadlessLoaderBlock == NULL)
+ {
+ UiMessageBox("Failed to allocate HLB Extension!");
+ while (TRUE);
+ return;
+ }
+ RtlCopyMemory(
+ Extension->HeadlessLoaderBlock,
+ &LoaderRedirectionInformation,
+ sizeof(HEADLESS_LOADER_BLOCK));
+ Extension->HeadlessLoaderBlock = PaToVa(Extension->HeadlessLoaderBlock);
+ }
-
++#endif
+ /* Load drivers database */
+ strcpy(MiscFiles, BootPath);
+ strcat(MiscFiles, "AppPatch\\drvmain.sdb");
+ Extension->DrvDBImage = PaToVa(WinLdrLoadModule(MiscFiles,
+ &Extension->DrvDBSize, LoaderRegistryData));
+
+ /* Convert extension and setup block pointers */
+ LoaderBlock->Extension = PaToVa(Extension);
+
+ if (LoaderBlock->SetupLdrBlock)
+ LoaderBlock->SetupLdrBlock = PaToVa(LoaderBlock->SetupLdrBlock);
+
+}
+
+BOOLEAN
+WinLdrLoadDeviceDriver(PLOADER_PARAMETER_BLOCK LoaderBlock,
+ LPSTR BootPath,
+ PUNICODE_STRING FilePath,
+ ULONG Flags,
+ PLDR_DATA_TABLE_ENTRY *DriverDTE)
+{
+ CHAR FullPath[1024];
+ CHAR DriverPath[1024];
+ CHAR DllName[1024];
+ PCHAR DriverNamePos;
+ BOOLEAN Status;
+ PVOID DriverBase;
+
+ // Separate the path to file name and directory path
+ _snprintf(DriverPath, sizeof(DriverPath), "%wZ", FilePath);
+ DriverNamePos = strrchr(DriverPath, '\\');
+ if (DriverNamePos != NULL)
+ {
+ // Copy the name
+ strcpy(DllName, DriverNamePos+1);
+
+ // Cut out the name from the path
+ *(DriverNamePos+1) = 0;
+ }
+ else
+ {
+ // There is no directory in the path
+ strcpy(DllName, DriverPath);
+ DriverPath[0] = 0;
+ }
+
+ DPRINTM(DPRINT_WINDOWS, "DriverPath: %s, DllName: %s, LPB %p\n", DriverPath, DllName, LoaderBlock);
+
+
+ // Check if driver is already loaded
+ Status = WinLdrCheckForLoadedDll(LoaderBlock, DllName, DriverDTE);
+ if (Status)
+ {
+ // We've got the pointer to its DTE, just return success
+ return TRUE;
+ }
+
+ // It's not loaded, we have to load it
+ _snprintf(FullPath, sizeof(FullPath), "%s%wZ", BootPath, FilePath);
+ Status = WinLdrLoadImage(FullPath, LoaderBootDriver, &DriverBase);
+ if (!Status)
+ return FALSE;
+
+ // Allocate a DTE for it
+ Status = WinLdrAllocateDataTableEntry(LoaderBlock, DllName, DllName, DriverBase, DriverDTE);
+ if (!Status)
+ {
+ DPRINTM(DPRINT_WINDOWS, "WinLdrAllocateDataTableEntry() failed\n");
+ return FALSE;
+ }
+
+ // Modify any flags, if needed
+ (*DriverDTE)->Flags |= Flags;
+
+ // Look for any dependencies it may have, and load them too
+ sprintf(FullPath,"%s%s", BootPath, DriverPath);
+ Status = WinLdrScanImportDescriptorTable(LoaderBlock, FullPath, *DriverDTE);
+ if (!Status)
+ {
+ DPRINTM(DPRINT_WINDOWS, "WinLdrScanImportDescriptorTable() failed for %s\n",
+ FullPath);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+BOOLEAN
+WinLdrLoadBootDrivers(PLOADER_PARAMETER_BLOCK LoaderBlock,
+ LPSTR BootPath)
+{
+ PLIST_ENTRY NextBd;
+ PBOOT_DRIVER_LIST_ENTRY BootDriver;
+ BOOLEAN Status;
+
+ // Walk through the boot drivers list
+ NextBd = LoaderBlock->BootDriverListHead.Flink;
+
+ while (NextBd != &LoaderBlock->BootDriverListHead)
+ {
+ BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, Link);
+
+ DPRINTM(DPRINT_WINDOWS, "BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
+ BootDriver->LdrEntry, &BootDriver->RegistryPath);
+
+ // Paths are relative (FIXME: Are they always relative?)
+
+ // Load it
+ Status = WinLdrLoadDeviceDriver(LoaderBlock, BootPath, &BootDriver->FilePath,
+ 0, &BootDriver->LdrEntry);
+
+ // If loading failed - cry loudly
+ //FIXME: Maybe remove it from the list and try to continue?
+ if (!Status)
+ {
+ UiMessageBox("Can't load boot driver!");
+ return FALSE;
+ }
+
+ // Convert the RegistryPath and DTE addresses to VA since we are not going to use it anymore
+ BootDriver->RegistryPath.Buffer = PaToVa(BootDriver->RegistryPath.Buffer);
+ BootDriver->FilePath.Buffer = PaToVa(BootDriver->FilePath.Buffer);
+ BootDriver->LdrEntry = PaToVa(BootDriver->LdrEntry);
+
+ NextBd = BootDriver->Link.Flink;
+ }
+
+ return TRUE;
+}
+
+PVOID WinLdrLoadModule(PCSTR ModuleName, ULONG *Size,
+ TYPE_OF_MEMORY MemoryType)
+{
+ ULONG FileId;
+ PVOID PhysicalBase;
+ FILEINFORMATION FileInfo;
+ ULONG FileSize;
+ ULONG Status;
+ ULONG BytesRead;
+
+ //CHAR ProgressString[256];
+
+ /* Inform user we are loading files */
+ //sprintf(ProgressString, "Loading %s...", FileName);
+ //UiDrawProgressBarCenter(1, 100, ProgressString);
+
+ DPRINTM(DPRINT_WINDOWS, "Loading module %s\n", ModuleName);
+ *Size = 0;
+
+ /* Open the image file */
+ Status = ArcOpen((PCHAR)ModuleName, OpenReadOnly, &FileId);
+ if (Status != ESUCCESS)
+ {
+ /* In case of errors, we just return, without complaining to the user */
+ return NULL;
+ }
+
+ /* Get this file's size */
+ Status = ArcGetFileInformation(FileId, &FileInfo);
+ if (Status != ESUCCESS)
+ {
+ ArcClose(FileId);
+ return NULL;
+ }
+ FileSize = FileInfo.EndingAddress.LowPart;
+ *Size = FileSize;
+
+ /* Allocate memory */
+ PhysicalBase = MmAllocateMemoryWithType(FileSize, MemoryType);
+ if (PhysicalBase == NULL)
+ {
+ ArcClose(FileId);
+ return NULL;
+ }
+
+ /* Load whole file */
+ Status = ArcRead(FileId, PhysicalBase, FileSize, &BytesRead);
+ ArcClose(FileId);
+ if (Status != ESUCCESS)
+ {
+ return NULL;
+ }
+
+ DPRINTM(DPRINT_WINDOWS, "Loaded %s at 0x%x with size 0x%x\n", ModuleName, PhysicalBase, FileSize);
+
+ return PhysicalBase;
+}
+
+
+USHORT
+WinLdrDetectVersion()
+{
+ LONG rc;
+ FRLDRHKEY hKey;
+
+ rc = RegOpenKey(
+ NULL,
+ L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server",
+ &hKey);
+ if (rc != ERROR_SUCCESS)
+ {
+ // Key doesn't exist; assume NT 4.0
+ return _WIN32_WINNT_NT4;
+ }
+
+ // We may here want to read the value of ProductVersion
+ return _WIN32_WINNT_WS03;
+}
+
+
+VOID
+LoadAndBootWindows(PCSTR OperatingSystemName,
+ PSTR SettingsValue,
+ USHORT OperatingSystemVersion)
+{
+ BOOLEAN HasSection;
+ char FullPath[MAX_PATH], SystemRoot[MAX_PATH], BootPath[MAX_PATH];
+ CHAR FileName[MAX_PATH];
+ CHAR BootOptions[256];
+ PCHAR File;
+ PCHAR PathSeparator;
+ PVOID NtosBase = NULL, HalBase = NULL, KdComBase = NULL;
+ BOOLEAN Status;
+ ULONG_PTR SectionId;
+ PLOADER_PARAMETER_BLOCK LoaderBlock, LoaderBlockVA;
+ KERNEL_ENTRY_POINT KiSystemStartup;
+ PLDR_DATA_TABLE_ENTRY KernelDTE, HalDTE, KdComDTE = NULL;
+ // Mm-related things
+ PVOID GdtIdt;
+ ULONG PcrBasePage=0;
+ ULONG TssBasePage=0;
+
+ // Open the operating system section
+ // specified in the .ini file
+ HasSection = IniOpenSection(OperatingSystemName, &SectionId);
+
+ UiDrawBackdrop();
+ UiDrawStatusText("Detecting Hardware...");
+ UiDrawProgressBarCenter(1, 100, "Loading NT...");
+
+ /* Read the system path is set in the .ini file */
+ if (!HasSection || !IniReadSettingByName(SectionId, "SystemPath", FullPath, sizeof(FullPath)))
+ {
+ strcpy(FullPath, OperatingSystemName);
+ }
+
+ /* Special case for LiveCD */
+ if (!_strnicmp(FullPath, "LiveCD", strlen("LiveCD")))
+ {
+ strcpy(BootPath, FullPath + strlen("LiveCD"));
+ MachDiskGetBootPath(FullPath, sizeof(FullPath));
+ strcat(FullPath, BootPath);
+ }
+
+ /* Convert FullPath to SystemRoot */
+ PathSeparator = strstr(FullPath, "\\");
+ strcpy(SystemRoot, PathSeparator);
+ strcat(SystemRoot, "\\");
+
+ /* Read booting options */
+ if (!HasSection || !IniReadSettingByName(SectionId, "Options", BootOptions, sizeof(BootOptions)))
+ {
+ /* Get options after the title */
+ const CHAR*p = SettingsValue;
+ while (*p == ' ' || *p == '"')
+ p++;
+ while (*p != '\0' && *p != '"')
+ p++;
+ strcpy(BootOptions, p);
+ DPRINTM(DPRINT_WINDOWS,"BootOptions: '%s'\n", BootOptions);
+ }
+
+ /* Append boot-time options */
+ AppendBootTimeOptions(BootOptions);
+
+ //
+ // Check if a ramdisk file was given
+ //
+ File = strstr(BootOptions, "/RDPATH=");
+ if (File)
+ {
+ //
+ // Copy the file name and everything else after it
+ //
+ strcpy(FileName, File + 8);
+
+ //
+ // Null-terminate
+ //
+ *strstr(FileName, " ") = ANSI_NULL;
+
+ //
+ // Load the ramdisk
+ //
+ RamDiskLoadVirtualFile(FileName);
+ }
+
+ /* Let user know we started loading */
+ UiDrawStatusText("Loading...");
+
+ /* append a backslash */
+ strcpy(BootPath, FullPath);
+ if ((strlen(BootPath)==0) ||
+ BootPath[strlen(BootPath)] != '\\')
+ strcat(BootPath, "\\");
+
+ DPRINTM(DPRINT_WINDOWS,"BootPath: '%s'\n", BootPath);
+
+ /* Allocate and minimalistic-initialize LPB */
+ AllocateAndInitLPB(&LoaderBlock);
+
++#ifndef _M_ARM
+ /* Setup redirection support */
+ WinLdrSetupEms(BootOptions);
++#endif
+ /* Detect hardware */
+ UseRealHeap = TRUE;
+ LoaderBlock->ConfigurationRoot = MachHwDetect();
+
+ /* Load Hive */
+ Status = WinLdrInitSystemHive(LoaderBlock, BootPath);
+ DPRINTM(DPRINT_WINDOWS, "SYSTEM hive loaded with status %d\n", Status);
+
+ if (OperatingSystemVersion == 0)
+ OperatingSystemVersion = WinLdrDetectVersion();
+
+ /* Load kernel */
+ strcpy(FileName, BootPath);
+ strcat(FileName, "SYSTEM32\\NTOSKRNL.EXE");
+ Status = WinLdrLoadImage(FileName, LoaderSystemCode, &NtosBase);
+ DPRINTM(DPRINT_WINDOWS, "Ntos loaded with status %d at %p\n", Status, NtosBase);
+
+ /* Load HAL */
+ strcpy(FileName, BootPath);
+ strcat(FileName, "SYSTEM32\\HAL.DLL");
+ Status = WinLdrLoadImage(FileName, LoaderHalCode, &HalBase);
+ DPRINTM(DPRINT_WINDOWS, "HAL loaded with status %d at %p\n", Status, HalBase);
+
+ /* Load kernel-debugger support dll */
+ if (OperatingSystemVersion > _WIN32_WINNT_WIN2K)
+ {
+ strcpy(FileName, BootPath);
+ strcat(FileName, "SYSTEM32\\KDCOM.DLL");
+ Status = WinLdrLoadImage(FileName, LoaderBootDriver, &KdComBase);
+ DPRINTM(DPRINT_WINDOWS, "KdCom loaded with status %d at %p\n", Status, KdComBase);
+ }
+
+ /* Allocate data table entries for above-loaded modules */
+ WinLdrAllocateDataTableEntry(LoaderBlock, "ntoskrnl.exe",
+ "WINDOWS\\SYSTEM32\\NTOSKRNL.EXE", NtosBase, &KernelDTE);
+ WinLdrAllocateDataTableEntry(LoaderBlock, "hal.dll",
+ "WINDOWS\\SYSTEM32\\HAL.DLL", HalBase, &HalDTE);
+ if (OperatingSystemVersion > _WIN32_WINNT_WIN2K)
+ {
+ WinLdrAllocateDataTableEntry(LoaderBlock, "kdcom.dll",
+ "WINDOWS\\SYSTEM32\\KDCOM.DLL", KdComBase, &KdComDTE);
+ }
+
+ /* Load all referenced DLLs for kernel, HAL and kdcom.dll */
+ strcpy(FileName, BootPath);
+ strcat(FileName, "SYSTEM32\\");
+ WinLdrScanImportDescriptorTable(LoaderBlock, FileName, KernelDTE);
+ WinLdrScanImportDescriptorTable(LoaderBlock, FileName, HalDTE);
+ if (KdComDTE)
+ WinLdrScanImportDescriptorTable(LoaderBlock, FileName, KdComDTE);
+
+ /* Load NLS data, OEM font, and prepare boot drivers list */
+ Status = WinLdrScanSystemHive(LoaderBlock, BootPath);
+ DPRINTM(DPRINT_WINDOWS, "SYSTEM hive scanned with status %d\n", Status);
+
+ /* Load boot drivers */
+ Status = WinLdrLoadBootDrivers(LoaderBlock, BootPath);
+ DPRINTM(DPRINT_WINDOWS, "Boot drivers loaded with status %d\n", Status);
+
+ /* Alloc PCR, TSS, do magic things with the GDT/IDT */
+ WinLdrSetupForNt(LoaderBlock, &GdtIdt, &PcrBasePage, &TssBasePage);
+
+ /* Initialize Phase 1 - no drivers loading anymore */
+ WinLdrInitializePhase1(LoaderBlock, BootOptions, SystemRoot, BootPath, OperatingSystemVersion);
+
+ /* Save entry-point pointer and Loader block VAs */
+ KiSystemStartup = (KERNEL_ENTRY_POINT)KernelDTE->EntryPoint;
+ LoaderBlockVA = PaToVa(LoaderBlock);
+
+ /* "Stop all motors", change videomode */
+ if (OperatingSystemVersion < _WIN32_WINNT_WIN2K)
+ MachPrepareForReactOS(TRUE);
+ else
+ MachPrepareForReactOS(FALSE);
+
+ /* Debugging... */
+ //DumpMemoryAllocMap();
+
+ /* Turn on paging mode of CPU*/
+ WinLdrTurnOnPaging(LoaderBlock, PcrBasePage, TssBasePage, GdtIdt);
+
+ /* Save final value of LoaderPagesSpanned */
+ LoaderBlockVA->Extension->LoaderPagesSpanned = LoaderPagesSpanned;
+
+ DPRINTM(DPRINT_WINDOWS, "Hello from paged mode, KiSystemStartup %p, LoaderBlockVA %p!\n",
+ KiSystemStartup, LoaderBlockVA);
+
+ WinLdrpDumpMemoryDescriptors(LoaderBlockVA);
+ WinLdrpDumpBootDriver(LoaderBlockVA);
+ WinLdrpDumpArcDisks(LoaderBlockVA);
+
+ //FIXME: If I substitute this debugging checkpoint, GCC will "optimize away" the code below
+ //while (1) {};
+ /*asm(".intel_syntax noprefix\n");
+ asm("test1:\n");
+ asm("jmp test1\n");
+ asm(".att_syntax\n");*/
+
+ /* Pass control */
+ (*KiSystemStartup)(LoaderBlockVA);
+
+ return;
+}
+
+VOID
+WinLdrpDumpMemoryDescriptors(PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+ PLIST_ENTRY NextMd;
+ PMEMORY_ALLOCATION_DESCRIPTOR MemoryDescriptor;
+
+ NextMd = LoaderBlock->MemoryDescriptorListHead.Flink;
+
+ while (NextMd != &LoaderBlock->MemoryDescriptorListHead)
+ {
+ MemoryDescriptor = CONTAINING_RECORD(NextMd, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry);
+
+ DPRINTM(DPRINT_WINDOWS, "BP %08X PC %04X MT %d\n", MemoryDescriptor->BasePage,
+ MemoryDescriptor->PageCount, MemoryDescriptor->MemoryType);
+
+ NextMd = MemoryDescriptor->ListEntry.Flink;
+ }
+}
+
+VOID
+WinLdrpDumpBootDriver(PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+ PLIST_ENTRY NextBd;
+ PBOOT_DRIVER_LIST_ENTRY BootDriver;
+
+ NextBd = LoaderBlock->BootDriverListHead.Flink;
+
+ while (NextBd != &LoaderBlock->BootDriverListHead)
+ {
+ BootDriver = CONTAINING_RECORD(NextBd, BOOT_DRIVER_LIST_ENTRY, Link);
+
+ DPRINTM(DPRINT_WINDOWS, "BootDriver %wZ DTE %08X RegPath: %wZ\n", &BootDriver->FilePath,
+ BootDriver->LdrEntry, &BootDriver->RegistryPath);
+
+ NextBd = BootDriver->Link.Flink;
+ }
+}
+
+VOID
+WinLdrpDumpArcDisks(PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+ PLIST_ENTRY NextBd;
+ PARC_DISK_SIGNATURE ArcDisk;
+
+ NextBd = LoaderBlock->ArcDiskInformation->DiskSignatureListHead.Flink;
+
+ while (NextBd != &LoaderBlock->ArcDiskInformation->DiskSignatureListHead)
+ {
+ ArcDisk = CONTAINING_RECORD(NextBd, ARC_DISK_SIGNATURE, ListEntry);
+
+ DPRINTM(DPRINT_WINDOWS, "ArcDisk %s checksum: 0x%X, signature: 0x%X\n",
+ ArcDisk->ArcName, ArcDisk->CheckSum, ArcDisk->Signature);
+
+ NextBd = ArcDisk->ListEntry.Flink;
+ }
+}
+
+
--- /dev/null
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+#ifndef _INC_SETJMP
+#define _INC_SETJMP
+
+#include <crtdefs.h>
+
+#pragma pack(push,_CRT_PACKING)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if (defined(_X86_) && !defined(__x86_64))
+
+#define _JBLEN 16
+#define _JBTYPE int
+
+ typedef struct __JUMP_BUFFER {
+ unsigned long Ebp;
+ unsigned long Ebx;
+ unsigned long Edi;
+ unsigned long Esi;
+ unsigned long Esp;
+ unsigned long Eip;
+ unsigned long Registration;
+ unsigned long TryLevel;
+ unsigned long Cookie;
+ unsigned long UnwindFunc;
+ unsigned long UnwindData[6];
+ } _JUMP_BUFFER;
+
+#elif defined(__ia64__)
+
+ typedef _CRT_ALIGN(16) struct _SETJMP_FLOAT128 {
+ __MINGW_EXTENSION __int64 LowPart;
+ __MINGW_EXTENSION __int64 HighPart;
+ } SETJMP_FLOAT128;
+
+#define _JBLEN 33
+ typedef SETJMP_FLOAT128 _JBTYPE;
+
+ typedef struct __JUMP_BUFFER {
+
+ unsigned long iAReserved[6];
+
+ unsigned long Registration;
+ unsigned long TryLevel;
+ unsigned long Cookie;
+ unsigned long UnwindFunc;
+
+ unsigned long UnwindData[6];
+
+ SETJMP_FLOAT128 FltS0;
+ SETJMP_FLOAT128 FltS1;
+ SETJMP_FLOAT128 FltS2;
+ SETJMP_FLOAT128 FltS3;
+ SETJMP_FLOAT128 FltS4;
+ SETJMP_FLOAT128 FltS5;
+ SETJMP_FLOAT128 FltS6;
+ SETJMP_FLOAT128 FltS7;
+ SETJMP_FLOAT128 FltS8;
+ SETJMP_FLOAT128 FltS9;
+ SETJMP_FLOAT128 FltS10;
+ SETJMP_FLOAT128 FltS11;
+ SETJMP_FLOAT128 FltS12;
+ SETJMP_FLOAT128 FltS13;
+ SETJMP_FLOAT128 FltS14;
+ SETJMP_FLOAT128 FltS15;
+ SETJMP_FLOAT128 FltS16;
+ SETJMP_FLOAT128 FltS17;
+ SETJMP_FLOAT128 FltS18;
+ SETJMP_FLOAT128 FltS19;
+ __MINGW_EXTENSION __int64 FPSR;
+ __MINGW_EXTENSION __int64 StIIP;
+ __MINGW_EXTENSION __int64 BrS0;
+ __MINGW_EXTENSION __int64 BrS1;
+ __MINGW_EXTENSION __int64 BrS2;
+ __MINGW_EXTENSION __int64 BrS3;
+ __MINGW_EXTENSION __int64 BrS4;
+ __MINGW_EXTENSION __int64 IntS0;
+ __MINGW_EXTENSION __int64 IntS1;
+ __MINGW_EXTENSION __int64 IntS2;
+ __MINGW_EXTENSION __int64 IntS3;
+ __MINGW_EXTENSION __int64 RsBSP;
+ __MINGW_EXTENSION __int64 RsPFS;
+ __MINGW_EXTENSION __int64 ApUNAT;
+ __MINGW_EXTENSION __int64 ApLC;
+ __MINGW_EXTENSION __int64 IntSp;
+ __MINGW_EXTENSION __int64 IntNats;
+ __MINGW_EXTENSION __int64 Preds;
+
+ } _JUMP_BUFFER;
+
+#elif defined(__x86_64)
+
+ typedef _CRT_ALIGN(16) struct _SETJMP_FLOAT128 {
+ __MINGW_EXTENSION unsigned __int64 Part[2];
+ } SETJMP_FLOAT128;
+
+#define _JBLEN 16
+ typedef SETJMP_FLOAT128 _JBTYPE;
+
+ typedef struct _JUMP_BUFFER {
+ __MINGW_EXTENSION unsigned __int64 Frame;
+ __MINGW_EXTENSION unsigned __int64 Rbx;
+ __MINGW_EXTENSION unsigned __int64 Rsp;
+ __MINGW_EXTENSION unsigned __int64 Rbp;
+ __MINGW_EXTENSION unsigned __int64 Rsi;
+ __MINGW_EXTENSION unsigned __int64 Rdi;
+ __MINGW_EXTENSION unsigned __int64 R12;
+ __MINGW_EXTENSION unsigned __int64 R13;
+ __MINGW_EXTENSION unsigned __int64 R14;
+ __MINGW_EXTENSION unsigned __int64 R15;
+ __MINGW_EXTENSION unsigned __int64 Rip;
+ __MINGW_EXTENSION unsigned __int64 Spare;
+ SETJMP_FLOAT128 Xmm6;
+ SETJMP_FLOAT128 Xmm7;
+ SETJMP_FLOAT128 Xmm8;
+ SETJMP_FLOAT128 Xmm9;
+ SETJMP_FLOAT128 Xmm10;
+ SETJMP_FLOAT128 Xmm11;
+ SETJMP_FLOAT128 Xmm12;
+ SETJMP_FLOAT128 Xmm13;
+ SETJMP_FLOAT128 Xmm14;
+ SETJMP_FLOAT128 Xmm15;
+ } _JUMP_BUFFER;
+
++#elif defined(_M_ARM)
++
++#define _JBLEN 11
++#define _JBTYPE int
++
++#else
++
++#error Define Setjmp for this architecture!
++
+#endif
+
+#ifndef _JMP_BUF_DEFINED
+ typedef _JBTYPE jmp_buf[_JBLEN];
+#define _JMP_BUF_DEFINED
+#endif
+
+#ifdef USE_MINGW_SETJMP_TWO_ARGS
+#ifndef _INC_SETJMPEX
+#if defined(__x86_64)
+# define mingw_getsp() \
+ ({ void* value; __asm__ __volatile__("movq %%rsp, %[value]" : [value] "=r" (value)); value; })
+#elif defined(_X86_)
+# define mingw_getsp() \
+ ({ void* value; __asm__ __volatile__("movl %%esp, %[value]" : [value] "=r" (value)); value; })
+#endif
+#define setjmp(BUF) _setjmp((BUF),mingw_getsp())
+ int __cdecl __MINGW_NOTHROW _setjmp(jmp_buf _Buf,void *_Ctx);
+#else /* _INC_SETJMPEX */
+#undef setjmp
+#define setjmp(BUF) _setjmpex((BUF),mingw_getsp())
+#define setjmpex(BUF) _setjmpex((BUF),mingw_getsp())
+ int __cdecl __MINGW_NOTHROW _setjmpex(jmp_buf _Buf,void *_Ctx);
+#endif /* _INC_SETJMPEX */
+#else /* !USE_MINGW_SETJMP_TWO_ARGS */
+#ifndef _INC_SETJMPEX
+#define setjmp _setjmp
+#endif
+ int __cdecl __MINGW_NOTHROW setjmp(jmp_buf _Buf);
+#endif /* !USE_MINGW_SETJMP_TWO_ARGS */
+
+ __declspec(noreturn) __MINGW_NOTHROW void __cdecl ms_longjmp(jmp_buf _Buf,int _Value)/* throw(...)*/;
+ __declspec(noreturn) __MINGW_NOTHROW void __cdecl longjmp(jmp_buf _Buf,int _Value);
+
+#ifdef __cplusplus
+}
+#endif
+
+#pragma pack(pop)
+#endif
--- /dev/null
-
- #if defined (_STDDEF_H) || defined (__need_NULL)
- #undef NULL /* in case <stdio.h> has defined it. */
- #ifdef __GNUG__
- #define NULL __null
- #else /* G++ */
- #ifndef __cplusplus
- #define NULL ((void *)0)
- #else /* C++ */
+/**
+ * This file has no copyright assigned and is placed in the Public Domain.
+ * This file is part of the w64 mingw-runtime package.
+ * No warranty is given; refer to the file DISCLAIMER within this package.
+ */
+
+#include <crtdefs.h>
+
+#ifndef _INC_STDDEF
+#define _INC_STDDEF
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <errno.h>
+
+ _CRTIMP extern unsigned long __cdecl __threadid(void);
+#define _threadid (__threadid())
+ _CRTIMP extern uintptr_t __cdecl __threadhandle(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*
+ * ISO C Standard: 7.17 Common definitions <stddef.h>
+ */
+#if (!defined(_STDDEF_H) && !defined(_STDDEF_H_) && !defined(_ANSI_STDDEF_H) \
+ && !defined(__STDDEF_H__)) \
+ || defined(__need_wchar_t) || defined(__need_size_t) \
+ || defined(__need_ptrdiff_t) || defined(__need_NULL) \
+ || defined(__need_wint_t)
+
+/* Any one of these symbols __need_* means that GNU libc
+ wants us just to define one data type. So don't define
+ the symbols that indicate this file's entire job has been done. */
+#if (!defined(__need_wchar_t) && !defined(__need_size_t) \
+ && !defined(__need_ptrdiff_t) && !defined(__need_NULL) \
+ && !defined(__need_wint_t))
+#define _STDDEF_H
+#define _STDDEF_H_
+/* snaroff@next.com says the NeXT needs this. */
+#define _ANSI_STDDEF_H
+/* Irix 5.1 needs this. */
+#define __STDDEF_H__
+#endif
+
+#ifndef __sys_stdtypes_h
+/* In 4.3bsd-net2, machine/ansi.h defines these symbols, which are
+ defined if the corresponding type is *not* defined.
+ FreeBSD-2.1 defines _MACHINE_ANSI_H_ instead of _ANSI_H_ */
+#if defined(_ANSI_H_) || defined(_MACHINE_ANSI_H_)
+#if !defined(_SIZE_T_) && !defined(_BSD_SIZE_T_)
+#define _SIZE_T
+#endif
+#if !defined(_PTRDIFF_T_) && !defined(_BSD_PTRDIFF_T_)
+#define _PTRDIFF_T
+#endif
+/* On BSD/386 1.1, at least, machine/ansi.h defines _BSD_WCHAR_T_
+ instead of _WCHAR_T_. */
+#if !defined(_WCHAR_T_) && !defined(_BSD_WCHAR_T_)
+#ifndef _BSD_WCHAR_T_
+#define _WCHAR_T
+#endif
+#endif
+/* Undef _FOO_T_ if we are supposed to define foo_t. */
+#if defined (__need_ptrdiff_t) || defined (_STDDEF_H_)
+#undef _PTRDIFF_T_
+#undef _BSD_PTRDIFF_T_
+#endif
+#if defined (__need_size_t) || defined (_STDDEF_H_)
+#undef _SIZE_T_
+#undef _BSD_SIZE_T_
+#endif
+#if defined (__need_wchar_t) || defined (_STDDEF_H_)
+#undef _WCHAR_T_
+#undef _BSD_WCHAR_T_
+#endif
+#endif /* defined(_ANSI_H_) || defined(_MACHINE_ANSI_H_) */
+
+/* Sequent's header files use _PTRDIFF_T_ in some conflicting way.
+ Just ignore it. */
+#if defined (__sequent__) && defined (_PTRDIFF_T_)
+#undef _PTRDIFF_T_
+#endif
+
+/* On VxWorks, <type/vxTypesBase.h> may have defined macros like
+ _TYPE_size_t which will typedef size_t. fixincludes patched the
+ vxTypesBase.h so that this macro is only defined if _GCC_SIZE_T is
+ not defined, and so that defining this macro defines _GCC_SIZE_T.
+ If we find that the macros are still defined at this point, we must
+ invoke them so that the type is defined as expected. */
+#if defined (_TYPE_ptrdiff_t) && (defined (__need_ptrdiff_t) || defined (_STDDEF_H_))
+_TYPE_ptrdiff_t;
+#undef _TYPE_ptrdiff_t
+#endif
+#if defined (_TYPE_size_t) && (defined (__need_size_t) || defined (_STDDEF_H_))
+_TYPE_size_t;
+#undef _TYPE_size_t
+#endif
+#if defined (_TYPE_wchar_t) && (defined (__need_wchar_t) || defined (_STDDEF_H_))
+_TYPE_wchar_t;
+#undef _TYPE_wchar_t
+#endif
+
+/* In case nobody has defined these types, but we aren't running under
+ GCC 2.00, make sure that __PTRDIFF_TYPE__, __SIZE_TYPE__, and
+ __WCHAR_TYPE__ have reasonable values. This can happen if the
+ parts of GCC is compiled by an older compiler, that actually
+ include gstddef.h, such as collect2. */
+
+/* Signed type of difference of two pointers. */
+
+/* Define this type if we are doing the whole job,
+ or if we want this type in particular. */
+#if defined (_STDDEF_H) || defined (__need_ptrdiff_t)
+#ifndef _PTRDIFF_T /* in case <sys/types.h> has defined it. */
+#ifndef _T_PTRDIFF_
+#ifndef _T_PTRDIFF
+#ifndef __PTRDIFF_T
+#ifndef _PTRDIFF_T_
+#ifndef _BSD_PTRDIFF_T_
+#ifndef ___int_ptrdiff_t_h
+#ifndef _GCC_PTRDIFF_T
+#define _PTRDIFF_T
+#define _T_PTRDIFF_
+#define _T_PTRDIFF
+#define __PTRDIFF_T
+#define _PTRDIFF_T_
+#define _BSD_PTRDIFF_T_
+#define ___int_ptrdiff_t_h
+#define _GCC_PTRDIFF_T
+#ifndef __PTRDIFF_TYPE__
+#ifdef _WIN64
+#define __PTRDIFF_TYPE__ long long int
+#else
+#define __PTRDIFF_TYPE__ long int
+#endif
+#endif
+#ifndef _PTRDIFF_T_DEFINED
+#define _PTRDIFF_T_DEFINED
+__MINGW_EXTENSION typedef __PTRDIFF_TYPE__ ptrdiff_t;
+#endif
+#endif /* _GCC_PTRDIFF_T */
+#endif /* ___int_ptrdiff_t_h */
+#endif /* _BSD_PTRDIFF_T_ */
+#endif /* _PTRDIFF_T_ */
+#endif /* __PTRDIFF_T */
+#endif /* _T_PTRDIFF */
+#endif /* _T_PTRDIFF_ */
+#endif /* _PTRDIFF_T */
+
+/* If this symbol has done its job, get rid of it. */
+#undef __need_ptrdiff_t
+
+#endif /* _STDDEF_H or __need_ptrdiff_t. */
+
+/* Unsigned type of `sizeof' something. */
+
+/* Define this type if we are doing the whole job,
+ or if we want this type in particular. */
+#if defined (_STDDEF_H) || defined (__need_size_t)
+#ifndef __size_t__ /* BeOS */
+#ifndef __SIZE_T__ /* Cray Unicos/Mk */
+#ifndef _SIZE_T /* in case <sys/types.h> has defined it. */
+#ifndef _SYS_SIZE_T_H
+#ifndef _T_SIZE_
+#ifndef _T_SIZE
+#ifndef __SIZE_T
+#ifndef _SIZE_T_
+#ifndef _BSD_SIZE_T_
+#ifndef _SIZE_T_DEFINED_
+#ifndef _SIZE_T_DEFINED
+#ifndef _BSD_SIZE_T_DEFINED_ /* Darwin */
+#ifndef _SIZE_T_DECLARED /* FreeBSD 5 */
+#ifndef ___int_size_t_h
+#ifndef _GCC_SIZE_T
+#ifndef _SIZET_
+#ifndef __size_t
+#define __size_t__ /* BeOS */
+#define __SIZE_T__ /* Cray Unicos/Mk */
+#define _SIZE_T
+#define _SYS_SIZE_T_H
+#define _T_SIZE_
+#define _T_SIZE
+#define __SIZE_T
+#define _SIZE_T_
+#define _BSD_SIZE_T_
+#define _SIZE_T_DEFINED_
+#define _SIZE_T_DEFINED
+#define _BSD_SIZE_T_DEFINED_ /* Darwin */
+#define _SIZE_T_DECLARED /* FreeBSD 5 */
+#define ___int_size_t_h
+#define _GCC_SIZE_T
+#define _SIZET_
+#if defined (__FreeBSD__) && (__FreeBSD__ >= 5)
+/* __size_t is a typedef on FreeBSD 5!, must not trash it. */
+#else
+#define __size_t
+#endif
+#ifndef __SIZE_TYPE__
+#ifdef _WIN64
+#define __SIZE_TYPE__ long long unsigned int
+#else
+#define __SIZE_TYPE__ long unsigned int
+#endif
+#endif
+#if !(defined (__GNUG__) && defined (size_t))
+__MINGW_EXTENSION typedef __SIZE_TYPE__ size_t;
+#ifdef __BEOS__
+typedef long ssize_t;
+#endif /* __BEOS__ */
+#endif /* !(defined (__GNUG__) && defined (size_t)) */
+#endif /* __size_t */
+#endif /* _SIZET_ */
+#endif /* _GCC_SIZE_T */
+#endif /* ___int_size_t_h */
+#endif /* _SIZE_T_DECLARED */
+#endif /* _BSD_SIZE_T_DEFINED_ */
+#endif /* _SIZE_T_DEFINED */
+#endif /* _SIZE_T_DEFINED_ */
+#endif /* _BSD_SIZE_T_ */
+#endif /* _SIZE_T_ */
+#endif /* __SIZE_T */
+#endif /* _T_SIZE */
+#endif /* _T_SIZE_ */
+#endif /* _SYS_SIZE_T_H */
+#endif /* _SIZE_T */
+#endif /* __SIZE_T__ */
+#endif /* __size_t__ */
+#undef __need_size_t
+#endif /* _STDDEF_H or __need_size_t. */
+
+
+/* Wide character type.
+ Locale-writers should change this as necessary to
+ be big enough to hold unique values not between 0 and 127,
+ and not (wchar_t) -1, for each defined multibyte character. */
+
+/* Define this type if we are doing the whole job,
+ or if we want this type in particular. */
+#if defined (_STDDEF_H) || defined (__need_wchar_t)
+#ifndef __wchar_t__ /* BeOS */
+#ifndef __WCHAR_T__ /* Cray Unicos/Mk */
+#ifndef _WCHAR_T
+#ifndef _T_WCHAR_
+#ifndef _T_WCHAR
+#ifndef __WCHAR_T
+#ifndef _WCHAR_T_
+#ifndef _BSD_WCHAR_T_
+#ifndef _BSD_WCHAR_T_DEFINED_ /* Darwin */
+#ifndef _BSD_RUNE_T_DEFINED_ /* Darwin */
+#ifndef _WCHAR_T_DECLARED /* FreeBSD 5 */
+#ifndef _WCHAR_T_DEFINED_
+#ifndef _WCHAR_T_DEFINED
+#ifndef _WCHAR_T_H
+#ifndef ___int_wchar_t_h
+#ifndef __INT_WCHAR_T_H
+#ifndef _GCC_WCHAR_T
+#define __wchar_t__ /* BeOS */
+#define __WCHAR_T__ /* Cray Unicos/Mk */
+#define _WCHAR_T
+#define _T_WCHAR_
+#define _T_WCHAR
+#define __WCHAR_T
+#define _WCHAR_T_
+#define _BSD_WCHAR_T_
+#define _WCHAR_T_DEFINED_
+#define _WCHAR_T_DEFINED
+#define _WCHAR_T_H
+#define ___int_wchar_t_h
+#define __INT_WCHAR_T_H
+#define _GCC_WCHAR_T
+#define _WCHAR_T_DECLARED
+
+/* On BSD/386 1.1, at least, machine/ansi.h defines _BSD_WCHAR_T_
+ instead of _WCHAR_T_, and _BSD_RUNE_T_ (which, unlike the other
+ symbols in the _FOO_T_ family, stays defined even after its
+ corresponding type is defined). If we define wchar_t, then we
+ must undef _WCHAR_T_; for BSD/386 1.1 (and perhaps others), if
+ we undef _WCHAR_T_, then we must also define rune_t, since
+ headers like runetype.h assume that if machine/ansi.h is included,
+ and _BSD_WCHAR_T_ is not defined, then rune_t is available.
+ machine/ansi.h says, "Note that _WCHAR_T_ and _RUNE_T_ must be of
+ the same type." */
+#ifdef _BSD_WCHAR_T_
+#undef _BSD_WCHAR_T_
+#ifdef _BSD_RUNE_T_
+#if !defined (_ANSI_SOURCE) && !defined (_POSIX_SOURCE)
+typedef _BSD_RUNE_T_ rune_t;
+#define _BSD_WCHAR_T_DEFINED_
+#define _BSD_RUNE_T_DEFINED_ /* Darwin */
+#if defined (__FreeBSD__) && (__FreeBSD__ < 5)
+/* Why is this file so hard to maintain properly? In contrast to
+ the comment above regarding BSD/386 1.1, on FreeBSD for as long
+ as the symbol has existed, _BSD_RUNE_T_ must not stay defined or
+ redundant typedefs will occur when stdlib.h is included after this file. */
+#undef _BSD_RUNE_T_
+#endif
+#endif
+#endif
+#endif
+
+#ifndef __WCHAR_TYPE__
+#define __WCHAR_TYPE__ unsigned short
+#endif
+#ifndef __cplusplus
+typedef __WCHAR_TYPE__ wchar_t;
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif /* _WCHAR_T_DECLARED */
+#endif /* _BSD_RUNE_T_DEFINED_ */
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif
+#endif /* __WCHAR_T__ */
+#endif /* __wchar_t__ */
+#undef __need_wchar_t
+#endif /* _STDDEF_H or __need_wchar_t. */
+
+/* In 4.3bsd-net2, leave these undefined to indicate that size_t, etc.
+ are already defined. */
+/* BSD/OS 3.1 and FreeBSD [23].x require the MACHINE_ANSI_H check here. */
+#if defined(_ANSI_H_) || defined(_MACHINE_ANSI_H_)
+/* The references to _GCC_PTRDIFF_T_, _GCC_SIZE_T_, and _GCC_WCHAR_T_
+ are probably typos and should be removed before 2.8 is released. */
+#ifdef _GCC_PTRDIFF_T_
+#undef _PTRDIFF_T_
+#undef _BSD_PTRDIFF_T_
+#endif
+#ifdef _GCC_SIZE_T_
+#undef _SIZE_T_
+#undef _BSD_SIZE_T_
+#endif
+#ifdef _GCC_WCHAR_T_
+#undef _WCHAR_T_
+#undef _BSD_WCHAR_T_
+#endif
+/* The following ones are the real ones. */
+#ifdef _GCC_PTRDIFF_T
+#undef _PTRDIFF_T_
+#undef _BSD_PTRDIFF_T_
+#endif
+#ifdef _GCC_SIZE_T
+#undef _SIZE_T_
+#undef _BSD_SIZE_T_
+#endif
+#ifdef _GCC_WCHAR_T
+#undef _WCHAR_T_
+#undef _BSD_WCHAR_T_
+#endif
+#endif /* _ANSI_H_ || _MACHINE_ANSI_H_ */
+
+#endif /* __sys_stdtypes_h */
+
+/* A null pointer constant. */
- #endif /* C++ */
- #endif /* G++ */
- #endif /* NULL not defined and <stddef.h> or need NULL. */
- #undef __need_NULL
++#ifndef NULL
++#ifdef __cplusplus
+#define NULL 0
++#else
++#define NULL ((void*)0)
++#endif
++#endif
+
+#ifndef offsetof
+
+/* Offset of member MEMBER in a struct of type TYPE. */
+#if defined(__GNUC__)
+#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
+#else
+#define offsetof(TYPE, MEMBER) ((size_t)&(((TYPE *)0)->MEMBER))
+#endif
+
+#endif /* !offsetof */
+
+#endif /* !_STDDEF_H && !_STDDEF_H_ && !_ANSI_STDDEF_H && !__STDDEF_H__
+ || __need_XXX was not defined before */
--- /dev/null
- ULONG Unknown1,
- ULONG Unknown2,
- ULONG Unknown3
+/*++ NDK Version: 0098
+
+Copyright (c) Alex Ionescu. All rights reserved.
+
+Header Name:
+
+ umfuncs.h
+
+Abstract:
+
+ Function definitions for Native DLL (ntdll) APIs exclusive to User Mode.
+
+Author:
+
+ Alex Ionescu (alexi@tinykrnl.org) - Updated - 27-Feb-2006
+
+--*/
+
+#ifndef _UMFUNCS_H
+#define _UMFUNCS_H
+
+//
+// Dependencies
+//
+#include <umtypes.h>
+#include <dbgktypes.h>
+
+//
+// Don't force inclusion of csrss header, leave this opaque.
+//
+struct _CSR_API_MESSAGE;
+struct _CSR_CAPTURE_BUFFER;
+
+//
+// CSR Functions
+//
+PVOID
+NTAPI
+CsrAllocateCaptureBuffer(
+ ULONG ArgumentCount,
+ ULONG BufferSize
+);
+
+ULONG
+NTAPI
+CsrAllocateMessagePointer(
+ struct _CSR_CAPTURE_BUFFER *CaptureBuffer,
+ ULONG MessageLength,
+ PVOID *CaptureData
+);
+
+VOID
+NTAPI
+CsrCaptureMessageBuffer(
+ struct _CSR_CAPTURE_BUFFER *CaptureBuffer,
+ PVOID MessageString,
+ ULONG StringLength,
+ PVOID *CapturedData
+);
+
+NTSTATUS
+NTAPI
+CsrClientConnectToServer(
+ PWSTR ObjectDirectory,
+ ULONG ServerId,
+ PVOID ConnectionInfo,
+ PULONG ConnectionInfoSize,
+ PBOOLEAN ServerToServerCall
+);
+
+NTSTATUS
+NTAPI
+CsrClientCallServer(
+ struct _CSR_API_MESSAGE *Request,
+ struct _CSR_CAPTURE_BUFFER *CaptureBuffer OPTIONAL,
+ ULONG ApiNumber,
+ ULONG RequestLength
+);
+
+NTSTATUS
+NTAPI
+CsrIdentifyAlertableThread(
+ VOID
+);
+
+VOID
+NTAPI
+CsrFreeCaptureBuffer(
+ struct _CSR_CAPTURE_BUFFER *CaptureBuffer
+);
+
+HANDLE
+NTAPI
+CsrGetProcessId(
+ VOID
+);
+
+NTSTATUS
+NTAPI
+CsrNewThread(VOID);
+
+NTSTATUS
+NTAPI
+CsrSetPriorityClass(
+ HANDLE Process,
+ PULONG PriorityClass
+);
+
+VOID
+NTAPI
+CsrProbeForRead(
+ IN PVOID Address,
+ IN ULONG Length,
+ IN ULONG Alignment
+);
+
+VOID
+NTAPI
+CsrProbeForWrite(
+ IN PVOID Address,
+ IN ULONG Length,
+ IN ULONG Alignment
+);
+
+//
+// Debug Functions
+//
+NTSYSAPI
+VOID
+NTAPI
+DbgBreakPointWithStatus(
+ IN ULONG Status
+);
+
+NTSTATUS
+NTAPI
+DbgUiConnectToDbg(
+ VOID
+);
+
+NTSTATUS
+NTAPI
+DbgUiContinue(
+ IN PCLIENT_ID ClientId,
+ IN NTSTATUS ContinueStatus
+);
+
+NTSTATUS
+NTAPI
+DbgUiDebugActiveProcess(
+ IN HANDLE Process
+);
+
+NTSTATUS
+NTAPI
+DbgUiStopDebugging(
+ IN HANDLE Process
+);
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+DbgUiWaitStateChange(
+ IN PDBGUI_WAIT_STATE_CHANGE DbgUiWaitStateCange,
+ IN PLARGE_INTEGER TimeOut
+);
+
+NTSTATUS
+NTAPI
+DbgUiConvertStateChangeStructure(
+ IN PDBGUI_WAIT_STATE_CHANGE WaitStateChange,
+ IN PVOID DebugEvent
+);
+
+VOID
+NTAPI
+DbgUiRemoteBreakin(
+ VOID
+);
+
+NTSTATUS
+NTAPI
+DbgUiIssueRemoteBreakin(
+ IN HANDLE Process
+);
+
+HANDLE
+NTAPI
+DbgUiGetThreadDebugObject(
+ VOID
+);
+
+//
+// Loader Functions
+//
+
+NTSTATUS
+NTAPI
+LdrAddRefDll(
+ IN ULONG Flags,
+ IN PVOID BaseAddress
+);
+
+NTSTATUS
+NTAPI
+LdrDisableThreadCalloutsForDll(
+ IN PVOID BaseAddress
+);
+
+NTSTATUS
+NTAPI
+LdrGetDllHandle(
+ IN PWSTR DllPath OPTIONAL,
+ IN PULONG DllCharacteristics,
+ IN PUNICODE_STRING DllName,
+ OUT PVOID *DllHandle
+);
+
+NTSTATUS
+NTAPI
+LdrFindEntryForAddress(
+ IN PVOID Address,
+ OUT PLDR_DATA_TABLE_ENTRY *Module
+);
+
+NTSTATUS
+NTAPI
+LdrGetProcedureAddress(
+ IN PVOID BaseAddress,
+ IN PANSI_STRING Name,
+ IN ULONG Ordinal,
+ OUT PVOID *ProcedureAddress
+);
+
+VOID
+NTAPI
+LdrInitializeThunk(
+ ULONG Unknown1,
+ ULONG Unknown2,
+ ULONG Unknown3,
+ ULONG Unknown4
+);
+
+NTSTATUS
+NTAPI
+LdrLoadDll(
+ IN PWSTR SearchPath OPTIONAL,
+ IN PULONG LoadFlags OPTIONAL,
+ IN PUNICODE_STRING Name,
+ OUT PVOID *BaseAddress OPTIONAL
+);
+
+PIMAGE_BASE_RELOCATION
+NTAPI
+LdrProcessRelocationBlock(
+ IN ULONG_PTR Address,
+ IN ULONG Count,
+ IN PUSHORT TypeOffset,
+ IN LONG_PTR Delta
+);
+
+NTSTATUS
+NTAPI
+LdrQueryImageFileExecutionOptions(
+ IN PUNICODE_STRING SubKey,
+ IN PCWSTR ValueName,
+ IN ULONG ValueSize,
+ OUT PVOID Buffer,
+ IN ULONG BufferSize,
+ OUT PULONG RetunedLength OPTIONAL
+);
+
+NTSTATUS
+NTAPI
+LdrQueryProcessModuleInformation(
+ IN PRTL_PROCESS_MODULES ModuleInformation OPTIONAL,
+ IN ULONG Size OPTIONAL,
+ OUT PULONG ReturnedSize
+);
+
+NTSTATUS
+NTAPI
+LdrShutdownProcess(
+ VOID
+);
+
+NTSTATUS
+NTAPI
+LdrShutdownThread(
+ VOID
+);
+
+NTSTATUS
+NTAPI
+LdrUnloadDll(
+ IN PVOID BaseAddress
+);
+
++typedef VOID NTAPI (*PLDR_CALLBACK)(PVOID CallbackContext, PVOID Name);
+NTSTATUS
+NTAPI
+LdrVerifyImageMatchesChecksum(
+ IN HANDLE FileHandle,
++ IN PLDR_CALLBACK Callback,
++ IN PVOID CallbackContext,
++ OUT PUSHORT ImageCharacterstics
+);
+
+#endif
--- /dev/null
+#ifndef _WINNT_H
+#define _WINNT_H
+
+#if !defined(__ROS_LONG64__)
+#ifdef __WINESRC__
+#define __ROS_LONG64__
+#endif
+#endif
+
+#ifdef __GNUC__
+#include <msvctarget.h>
+#endif
+
++#ifndef __ANONYMOUS_DEFINED
++#define __ANONYMOUS_DEFINED
++#ifndef NONAMELESSUNION
++#ifdef __GNUC__
++#define _ANONYMOUS_UNION __extension__
++#define _ANONYMOUS_STRUCT __extension__
++#elif defined(__WATCOMC__) || defined(_MSC_VER)
++#define _ANONYMOUS_UNION
++#define _ANONYMOUS_STRUCT
++#endif /* __GNUC__/__WATCOMC__ */
++#endif /* NONAMELESSUNION */
++#ifndef _ANONYMOUS_UNION
++#define _ANONYMOUS_UNION
++#define _UNION_NAME(x) x
++#define DUMMYUNIONNAME u
++#define DUMMYUNIONNAME1 u1
++#define DUMMYUNIONNAME2 u2
++#define DUMMYUNIONNAME3 u3
++#define DUMMYUNIONNAME4 u4
++#define DUMMYUNIONNAME5 u5
++#define DUMMYUNIONNAME6 u6
++#define DUMMYUNIONNAME7 u7
++#define DUMMYUNIONNAME8 u8
++#else
++#define _UNION_NAME(x)
++#define DUMMYUNIONNAME
++#define DUMMYUNIONNAME1
++#define DUMMYUNIONNAME2
++#define DUMMYUNIONNAME3
++#define DUMMYUNIONNAME4
++#define DUMMYUNIONNAME5
++#define DUMMYUNIONNAME6
++#define DUMMYUNIONNAME7
++#define DUMMYUNIONNAME8
++#endif
++#ifndef _ANONYMOUS_STRUCT
++#define _ANONYMOUS_STRUCT
++#define _STRUCT_NAME(x) x
++#define DUMMYSTRUCTNAME s
++#define DUMMYSTRUCTNAME1 s1
++#define DUMMYSTRUCTNAME2 s2
++#define DUMMYSTRUCTNAME3 s3
++#define DUMMYSTRUCTNAME4 s4
++#define DUMMYSTRUCTNAME5 s5
++#else
++#define _STRUCT_NAME(x)
++#define DUMMYSTRUCTNAME
++#define DUMMYSTRUCTNAME1
++#define DUMMYSTRUCTNAME2
++#define DUMMYSTRUCTNAME3
++#define DUMMYSTRUCTNAME4
++#define DUMMYSTRUCTNAME5
++#endif
++#endif /* __ANONYMOUS_DEFINED */
++
++
+#ifndef DECLSPEC_ALIGN
+# if defined(_MSC_VER) && (_MSC_VER >= 1300) && !defined(MIDL_PASS)
+# define DECLSPEC_ALIGN(x) __declspec(align(x))
+# elif defined(__GNUC__)
+# define DECLSPEC_ALIGN(x) __attribute__((aligned(x)))
+# else
+# define DECLSPEC_ALIGN(x)
+# endif
+#endif
+
+# define DECLSPEC_HIDDEN
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <excpt.h>
+#include <basetsd.h>
+#include <guiddef.h>
+
+#include <ctype.h>
+#undef __need_wchar_t
+
+#include <winerror.h>
+#include <stddef.h>
+#include <sdkddkver.h>
+
+#ifndef RC_INVOKED
+#include <string.h>
+
+/* FIXME: add more architectures. Is there a way to specify this in GCC? */
+#if defined(_M_AMD64)
+#undef UNALIGNED
+#define UNALIGNED __unaligned
+#else
+#define UNALIGNED
+#endif
+
+#ifndef DECLSPEC_NOVTABLE
+# if defined(_MSC_VER) && (_MSC_VER >= 1100) && defined(__cplusplus)
+# define DECLSPEC_NOVTABLE __declspec(novtable)
+# else
+# define DECLSPEC_NOVTABLE
+# endif
+#endif
+
+#ifndef DECLSPEC_ADDRSAFE
+#if (_MSC_VER >= 1200) && (defined(_M_ALPHA) || defined(_M_AXP64))
+#define DECLSPEC_ADDRSAFE __declspec(address_safe)
+#else
+#define DECLSPEC_ADDRSAFE
+#endif
+#endif
+
+/*#ifdef _WINE*/
+#if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)))
+#define __WINE_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
+#else
+#define __WINE_ALLOC_SIZE(x)
+#endif
+/*#endif*/
+
+#ifndef FORCEINLINE
+#if (_MSC_VER >= 1200)
+#define FORCEINLINE __forceinline
+#elif (_MSC_VER)
+#define FORCEINLINE __inline
+#else
+#define FORCEINLINE extern __inline__ __attribute__((always_inline))
+#endif
+#endif
+
+#if !defined(_NTSYSTEM_)
+#define NTSYSAPI DECLSPEC_IMPORT
+#define NTSYSCALLAPI DECLSPEC_IMPORT
+#else
+#define NTSYSAPI
+#if defined(_NTDLLBUILD_)
+#define NTSYSCALLAPI
+#else
+#define NTSYSCALLAPI DECLSPEC_ADDRSAFE
+#endif
+#endif
+
+#ifndef VOID
+#define VOID void
+#endif
+typedef char CHAR;
+typedef short SHORT;
+#if !defined(__ROS_LONG64__) || defined(_M_AMD64)
+typedef long LONG;
+#else
+typedef int LONG;
+#endif
+typedef char CCHAR, *PCCHAR;
+typedef void *PVOID;
+
+/* FIXME for __WIN64 */
+#ifndef __ptr64
+#define __ptr64
+#endif
+typedef void* __ptr64 PVOID64;
+
+#ifdef __cplusplus
+# define EXTERN_C extern "C"
+#else
+# define EXTERN_C extern
+#endif
+
+#define STDMETHODCALLTYPE __stdcall
+#define STDMETHODVCALLTYPE __cdecl
+#define STDAPICALLTYPE __stdcall
+#define STDAPIVCALLTYPE __cdecl
+
+#define STDAPI EXTERN_C HRESULT STDAPICALLTYPE
+#define STDAPI_(type) EXTERN_C type STDAPICALLTYPE
+#define STDMETHODIMP HRESULT STDMETHODCALLTYPE
+#define STDMETHODIMP_(type) type STDMETHODCALLTYPE
+#define STDAPIV EXTERN_C HRESULT STDAPIVCALLTYPE
+#define STDAPIV_(type) EXTERN_C type STDAPIVCALLTYPE
+#define STDMETHODIMPV HRESULT STDMETHODVCALLTYPE
+#define STDMETHODIMPV_(type) type STDMETHODVCALLTYPE
+
+/* C99 restrict support */
+#if defined(ENABLE_RESTRICTED) && !defined(MIDL_PASS) && !defined(RC_INVOKED)
+ #if defined(_MSC_VER) && defined(_M_MRX000)
+ #define RESTRICTED_POINTER __restrict
+ #elif defined(__GNUC__) && ((__GNUC__ > 2) || ((__GNUC__ == 2) && (__GNUC_MINOR__ >= 95)))
+ #define RESTRICTED_POINTER __restrict
+ #else
+ #define RESTRICTED_POINTER
+ #endif
+#else
+ #define RESTRICTED_POINTER
+#endif
+
+typedef wchar_t WCHAR;
+typedef WCHAR *PWCHAR,*LPWCH,*PWCH,*NWPSTR,*LPWSTR,*PWSTR,*PZZWSTR;
+typedef CONST WCHAR *LPCWCH,*PCWCH,*LPCWSTR,*PCWSTR,*PCZZWSTR;
+typedef CHAR *PCHAR,*LPCH,*PCH,*NPSTR,*LPSTR,*PSTR;
+typedef CONST CHAR *LPCCH,*PCCH,*PCSTR,*LPCSTR;
+typedef PWSTR *PZPWSTR;
+typedef CONST PWSTR *PCZPWSTR;
+typedef WCHAR UNALIGNED *LPUWSTR,*PUWSTR;
+typedef PCWSTR *PZPCWSTR;
+typedef CONST WCHAR UNALIGNED *LPCUWSTR,*PCUWSTR;
+typedef PSTR *PZPSTR;
+typedef CONST PSTR *PCZPSTR;
+typedef PCSTR *PZPCSTR;
+
+
+#ifdef UNICODE
+#ifndef _TCHAR_DEFINED
+#define _TCHAR_DEFINED
+ typedef WCHAR TCHAR,*PTCHAR;
+ typedef WCHAR TBYTE ,*PTBYTE;
+#endif
+ typedef LPWSTR LPTCH,PTCH,PTSTR,LPTSTR,LP;
+ typedef LPCWSTR PCTSTR,LPCTSTR;
+ typedef LPUWSTR PUTSTR,LPUTSTR;
+ typedef LPCUWSTR PCUTSTR,LPCUTSTR;
+#define __TEXT(quote) L##quote
+#else
+#ifndef _TCHAR_DEFINED
+#define _TCHAR_DEFINED
+ typedef char TCHAR,*PTCHAR;
+ typedef unsigned char TBYTE ,*PTBYTE;
+#endif
+ typedef LPSTR LPTCH,PTCH,PTSTR,LPTSTR,PUTSTR,LPUTSTR;
+ typedef LPCSTR PCTSTR,LPCTSTR,PCUTSTR,LPCUTSTR;
+#define __TEXT(quote) quote
+#endif
+
+#define TEXT(quote) __TEXT(quote)
+
+typedef SHORT *PSHORT;
+typedef LONG *PLONG;
+#ifdef STRICT
+typedef void *HANDLE;
+#define DECLARE_HANDLE(n) typedef struct n##__{int i;}*n
+#else
+typedef PVOID HANDLE;
+#define DECLARE_HANDLE(n) typedef HANDLE n
+#endif
+typedef HANDLE *PHANDLE;
+typedef DWORD LCID;
+typedef PDWORD PLCID;
+typedef WORD LANGID;
+#ifdef __GNUC__
+#define _HAVE_INT64
+#ifndef _INTEGRAL_MAX_BITS
+# define _INTEGRAL_MAX_BITS 64
+#endif
+#undef __int64
+#define __int64 long long
+#elif (defined(__WATCOMC__) || defined(_MSC_VER)) && (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 64 )
+#define _HAVE_INT64
+#endif /* __GNUC__/__WATCOMC */
+#if defined(_HAVE_INT64) || (defined(_INTEGRAL_MAX_BITS) && _INTEGRAL_MAX_BITS >= 64)
+typedef __int64 LONGLONG;
+typedef unsigned __int64 DWORDLONG;
+#else
+typedef double LONGLONG,DWORDLONG;
+#endif
+typedef LONGLONG *PLONGLONG;
+typedef DWORDLONG *PDWORDLONG;
+typedef DWORDLONG ULONGLONG,*PULONGLONG;
+typedef LONGLONG USN;
+#ifdef _HAVE_INT64
+#define Int32x32To64(a,b) ((LONGLONG)(a)*(LONGLONG)(b))
+#define UInt32x32To64(a,b) ((DWORDLONG)(a)*(DWORDLONG)(b))
+#define Int64ShllMod32(a,b) ((DWORDLONG)(a)<<(b))
+#define Int64ShraMod32(a,b) ((LONGLONG)(a)>>(b))
+#define Int64ShrlMod32(a,b) ((DWORDLONG)(a)>>(b))
+#endif
+#define ANSI_NULL ((CHAR)0)
+#define UNICODE_NULL ((WCHAR)0)
+typedef BYTE BOOLEAN,*PBOOLEAN;
+#endif
+typedef BYTE FCHAR;
+typedef WORD FSHORT;
+typedef DWORD FLONG;
+
+#define C_ASSERT(expr) extern char (*c_assert(void)) [(expr) ? 1 : -1]
+
+#include "intrin.h"
+
+#define NTAPI __stdcall
+#include <basetsd.h>
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4201)
+#pragma warning(disable:4214)
+#pragma warning(disable:4820)
+#endif
+
+#define ACE_OBJECT_TYPE_PRESENT 0x00000001
+#define ACE_INHERITED_OBJECT_TYPE_PRESENT 0x00000002
+#define APPLICATION_ERROR_MASK 0x20000000
+#define ERROR_SEVERITY_SUCCESS 0x00000000
+#define ERROR_SEVERITY_INFORMATIONAL 0x40000000
+#define ERROR_SEVERITY_WARNING 0x80000000
+#define ERROR_SEVERITY_ERROR 0xC0000000
+/* also in ddk/ntifs.h */
+#define COMPRESSION_FORMAT_NONE (0x0000)
+#define COMPRESSION_FORMAT_DEFAULT (0x0001)
+#define COMPRESSION_FORMAT_LZNT1 (0x0002)
+#define COMPRESSION_ENGINE_STANDARD (0x0000)
+#define COMPRESSION_ENGINE_MAXIMUM (0x0100)
+#define COMPRESSION_ENGINE_HIBER (0x0200)
+#define ACCESS_ALLOWED_ACE_TYPE (0x0)
+#define ACCESS_DENIED_ACE_TYPE (0x1)
+#define SYSTEM_AUDIT_ACE_TYPE (0x2)
+#define SYSTEM_ALARM_ACE_TYPE (0x3)
+/*end ntifs.h */
+#define ANYSIZE_ARRAY 1
+#define OBJECT_INHERIT_ACE 1
+#define CONTAINER_INHERIT_ACE 2
+#define NO_PROPAGATE_INHERIT_ACE 4
+#define INHERIT_ONLY_ACE 8
+#define INHERITED_ACE 10
+#define VALID_INHERIT_FLAGS 0x1F
+#define SUCCESSFUL_ACCESS_ACE_FLAG 64
+#define FAILED_ACCESS_ACE_FLAG 128
+#define DELETE 0x00010000L
+#define READ_CONTROL 0x20000L
+#define WRITE_DAC 0x40000L
+#define WRITE_OWNER 0x80000L
+#define SYNCHRONIZE 0x100000L
+#define STANDARD_RIGHTS_REQUIRED 0xF0000
+#define STANDARD_RIGHTS_READ 0x20000
+#define STANDARD_RIGHTS_WRITE 0x20000
+#define STANDARD_RIGHTS_EXECUTE 0x20000
+#define STANDARD_RIGHTS_ALL 0x1F0000
+#define SPECIFIC_RIGHTS_ALL 0xFFFF
+#define ACCESS_SYSTEM_SECURITY 0x1000000
+
+#define REG_STANDARD_FORMAT 1
+#define REG_LATEST_FORMAT 2
+#define REG_NO_COMPRESSION 4
+
+#ifndef WIN32_NO_STATUS
+
+#define STATUS_WAIT_0 ((DWORD)0x00000000)
+#define STATUS_ABANDONED_WAIT_0 ((DWORD)0x00000080)
+#define STATUS_USER_APC ((DWORD)0x000000C0)
+#define STATUS_TIMEOUT ((DWORD)0x00000102)
+#define STATUS_PENDING ((DWORD)0x00000103)
+#define STATUS_SEGMENT_NOTIFICATION ((DWORD)0x40000005)
+#define STATUS_GUARD_PAGE_VIOLATION ((DWORD)0x80000001)
+#define STATUS_DATATYPE_MISALIGNMENT ((DWORD)0x80000002)
+#define STATUS_BREAKPOINT ((DWORD)0x80000003)
+#define STATUS_SINGLE_STEP ((DWORD)0x80000004)
+#define STATUS_ACCESS_VIOLATION ((DWORD)0xC0000005)
+#define STATUS_IN_PAGE_ERROR ((DWORD)0xC0000006)
+#define STATUS_INVALID_HANDLE ((DWORD)0xC0000008)
+#define STATUS_NO_MEMORY ((DWORD)0xC0000017)
+#define STATUS_ILLEGAL_INSTRUCTION ((DWORD)0xC000001D)
+#define STATUS_NONCONTINUABLE_EXCEPTION ((DWORD)0xC0000025)
+#define STATUS_INVALID_DISPOSITION ((DWORD)0xC0000026)
+#define STATUS_ARRAY_BOUNDS_EXCEEDED ((DWORD)0xC000008C)
+#define STATUS_FLOAT_DENORMAL_OPERAND ((DWORD)0xC000008D)
+#define STATUS_FLOAT_DIVIDE_BY_ZERO ((DWORD)0xC000008E)
+#define STATUS_FLOAT_INEXACT_RESULT ((DWORD)0xC000008F)
+#define STATUS_FLOAT_INVALID_OPERATION ((DWORD)0xC0000090)
+#define STATUS_FLOAT_OVERFLOW ((DWORD)0xC0000091)
+#define STATUS_FLOAT_STACK_CHECK ((DWORD)0xC0000092)
+#define STATUS_FLOAT_UNDERFLOW ((DWORD)0xC0000093)
+#define STATUS_INTEGER_DIVIDE_BY_ZERO ((DWORD)0xC0000094)
+#define STATUS_INTEGER_OVERFLOW ((DWORD)0xC0000095)
+#define STATUS_PRIVILEGED_INSTRUCTION ((DWORD)0xC0000096)
+#define STATUS_STACK_OVERFLOW ((DWORD)0xC00000FD)
+#define STATUS_CONTROL_C_EXIT ((DWORD)0xC000013A)
+#define STATUS_FLOAT_MULTIPLE_FAULTS ((DWORD)0xC00002B4)
+#define STATUS_FLOAT_MULTIPLE_TRAPS ((DWORD)0xC00002B5)
+#define STATUS_REG_NAT_CONSUMPTION ((DWORD)0xC00002C9)
+#define STATUS_SXS_EARLY_DEACTIVATION ((DWORD)0xC015000F)
+#define STATUS_SXS_INVALID_DEACTIVATION ((DWORD)0xC0150010)
+
+#define DBG_EXCEPTION_HANDLED ((DWORD)0x00010001)
+#define DBG_CONTINUE ((DWORD)0x00010002)
+#define DBG_TERMINATE_THREAD ((DWORD)0x40010003)
+#define DBG_TERMINATE_PROCESS ((DWORD)0x40010004)
+#define DBG_CONTROL_C ((DWORD)0x40010005)
+#define DBG_CONTROL_BREAK ((DWORD)0x40010008)
+#define DBG_COMMAND_EXCEPTION ((DWORD)0x40010009)
+#define DBG_EXCEPTION_NOT_HANDLED ((DWORD)0x80010001)
+
+#endif /* WIN32_NO_STATUS */
+
+#define MAXIMUM_ALLOWED 0x2000000
+#define GENERIC_READ 0x80000000
+#define GENERIC_WRITE 0x40000000
+#define GENERIC_EXECUTE 0x20000000
+#define GENERIC_ALL 0x10000000
+
+#define INVALID_FILE_ATTRIBUTES ((DWORD)-1)
+
+/* Also in ddk/winddk.h */
+#define FILE_LIST_DIRECTORY 0x00000001
+#define FILE_READ_DATA 0x00000001
+#define FILE_ADD_FILE 0x00000002
+#define FILE_WRITE_DATA 0x00000002
+#define FILE_ADD_SUBDIRECTORY 0x00000004
+#define FILE_APPEND_DATA 0x00000004
+#define FILE_CREATE_PIPE_INSTANCE 0x00000004
+#define FILE_READ_EA 0x00000008
+#define FILE_READ_PROPERTIES 0x00000008
+#define FILE_WRITE_EA 0x00000010
+#define FILE_WRITE_PROPERTIES 0x00000010
+#define FILE_EXECUTE 0x00000020
+#define FILE_TRAVERSE 0x00000020
+#define FILE_DELETE_CHILD 0x00000040
+#define FILE_READ_ATTRIBUTES 0x00000080
+#define FILE_WRITE_ATTRIBUTES 0x00000100
+
+#define FILE_SHARE_READ 0x00000001
+#define FILE_SHARE_WRITE 0x00000002
+#define FILE_SHARE_DELETE 0x00000004
+#define FILE_SHARE_VALID_FLAGS 0x00000007
+
+#define FILE_ATTRIBUTE_READONLY 0x00000001
+#define FILE_ATTRIBUTE_HIDDEN 0x00000002
+#define FILE_ATTRIBUTE_SYSTEM 0x00000004
+#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
+#define FILE_ATTRIBUTE_ARCHIVE 0x00000020
+#define FILE_ATTRIBUTE_DEVICE 0x00000040
+#define FILE_ATTRIBUTE_NORMAL 0x00000080
+#define FILE_ATTRIBUTE_TEMPORARY 0x00000100
+#define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200
+#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
+#define FILE_ATTRIBUTE_COMPRESSED 0x00000800
+#define FILE_ATTRIBUTE_OFFLINE 0x00001000
+#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000
+#define FILE_ATTRIBUTE_ENCRYPTED 0x00004000
+#define FILE_ATTRIBUTE_VALID_FLAGS 0x00007fb7
+#define FILE_ATTRIBUTE_VALID_SET_FLAGS 0x000031a7
+
+#define FILE_COPY_STRUCTURED_STORAGE 0x00000041
+#define FILE_STRUCTURED_STORAGE 0x00000441
+
+#define FILE_VALID_OPTION_FLAGS 0x00ffffff
+#define FILE_VALID_PIPE_OPTION_FLAGS 0x00000032
+#define FILE_VALID_MAILSLOT_OPTION_FLAGS 0x00000032
+#define FILE_VALID_SET_FLAGS 0x00000036
+
+#define FILE_DIRECTORY_FILE 0x00000001
+#define FILE_WRITE_THROUGH 0x00000002
+#define FILE_SEQUENTIAL_ONLY 0x00000004
+#define FILE_NO_INTERMEDIATE_BUFFERING 0x00000008
+#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010
+#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020
+#define FILE_NON_DIRECTORY_FILE 0x00000040
+#define FILE_CREATE_TREE_CONNECTION 0x00000080
+#define FILE_COMPLETE_IF_OPLOCKED 0x00000100
+#define FILE_NO_EA_KNOWLEDGE 0x00000200
+#define FILE_OPEN_REMOTE_INSTANCE 0x00000400
+#define FILE_RANDOM_ACCESS 0x00000800
+#define FILE_DELETE_ON_CLOSE 0x00001000
+#define FILE_OPEN_BY_FILE_ID 0x00002000
+#define FILE_OPEN_FOR_BACKUP_INTENT 0x00004000
+#define FILE_NO_COMPRESSION 0x00008000
+#define FILE_RESERVE_OPFILTER 0x00100000
+#define FILE_OPEN_REPARSE_POINT 0x00200000
+#define FILE_OPEN_NO_RECALL 0x00400000
+#define FILE_OPEN_FOR_FREE_SPACE_QUERY 0x00800000
+
+#define FILE_ALL_ACCESS \
+ (STANDARD_RIGHTS_REQUIRED | \
+ SYNCHRONIZE | \
+ 0x1FF)
+
+#define FILE_GENERIC_EXECUTE \
+ (STANDARD_RIGHTS_EXECUTE | \
+ FILE_READ_ATTRIBUTES | \
+ FILE_EXECUTE | \
+ SYNCHRONIZE)
+
+#define FILE_GENERIC_READ \
+ (STANDARD_RIGHTS_READ | \
+ FILE_READ_DATA | \
+ FILE_READ_ATTRIBUTES | \
+ FILE_READ_EA | \
+ SYNCHRONIZE)
+
+#define FILE_GENERIC_WRITE \
+ (STANDARD_RIGHTS_WRITE | \
+ FILE_WRITE_DATA | \
+ FILE_WRITE_ATTRIBUTES | \
+ FILE_WRITE_EA | \
+ FILE_APPEND_DATA | \
+ SYNCHRONIZE)
+/* end winddk.h */
+/* also in ddk/ntifs.h */
+#define FILE_NOTIFY_CHANGE_FILE_NAME 0x00000001
+#define FILE_NOTIFY_CHANGE_DIR_NAME 0x00000002
+#define FILE_NOTIFY_CHANGE_NAME 0x00000003
+#define FILE_NOTIFY_CHANGE_ATTRIBUTES 0x00000004
+#define FILE_NOTIFY_CHANGE_SIZE 0x00000008
+#define FILE_NOTIFY_CHANGE_LAST_WRITE 0x00000010
+#define FILE_NOTIFY_CHANGE_LAST_ACCESS 0x00000020
+#define FILE_NOTIFY_CHANGE_CREATION 0x00000040
+#define FILE_NOTIFY_CHANGE_EA 0x00000080
+#define FILE_NOTIFY_CHANGE_SECURITY 0x00000100
+#define FILE_NOTIFY_CHANGE_STREAM_NAME 0x00000200
+#define FILE_NOTIFY_CHANGE_STREAM_SIZE 0x00000400
+#define FILE_NOTIFY_CHANGE_STREAM_WRITE 0x00000800
+#define FILE_NOTIFY_VALID_MASK 0x00000fff
+
+#define FILE_CASE_SENSITIVE_SEARCH 0x00000001
+#define FILE_CASE_PRESERVED_NAMES 0x00000002
+#define FILE_UNICODE_ON_DISK 0x00000004
+#define FILE_PERSISTENT_ACLS 0x00000008
+#define FILE_FILE_COMPRESSION 0x00000010
+#define FILE_VOLUME_QUOTAS 0x00000020
+#define FILE_SUPPORTS_SPARSE_FILES 0x00000040
+#define FILE_SUPPORTS_REPARSE_POINTS 0x00000080
+#define FILE_SUPPORTS_REMOTE_STORAGE 0x00000100
+#define FS_LFN_APIS 0x00004000
+#define FILE_VOLUME_IS_COMPRESSED 0x00008000
+#define FILE_SUPPORTS_OBJECT_IDS 0x00010000
+#define FILE_SUPPORTS_ENCRYPTION 0x00020000
+#define FILE_NAMED_STREAMS 0x00040000
+
+#define IO_COMPLETION_QUERY_STATE 0x0001
+#define IO_COMPLETION_MODIFY_STATE 0x0002
+#define IO_COMPLETION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3)
+/* end ntifs.h */
+
+/* also in ddk/winddk.h */
+#define DUPLICATE_CLOSE_SOURCE 0x00000001
+#define DUPLICATE_SAME_ACCESS 0x00000002
+/* end winddk.k */
+
+#define MAILSLOT_NO_MESSAGE ((DWORD)-1)
+#define MAILSLOT_WAIT_FOREVER ((DWORD)-1)
+#define PROCESS_TERMINATE 1
+#define PROCESS_CREATE_THREAD 2
+#define PROCESS_SET_SESSIONID 4
+#define PROCESS_VM_OPERATION 8
+#define PROCESS_VM_READ 16
+#define PROCESS_VM_WRITE 32
+#define PROCESS_CREATE_PROCESS 128
+#define PROCESS_SET_QUOTA 256
+#define PROCESS_SET_INFORMATION 512
+#define PROCESS_QUERY_INFORMATION 1024
+#define PROCESS_SUSPEND_RESUME 2048
+#define PROCESS_QUERY_LIMITED_INFORMATION 0x1000
+#define PROCESS_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0xFFF)
+#define PROCESS_DUP_HANDLE 64
+#define THREAD_TERMINATE 1
+#define THREAD_SUSPEND_RESUME 2
+#define THREAD_GET_CONTEXT 8
+#define THREAD_SET_CONTEXT 16
+#define THREAD_SET_INFORMATION 32
+#define THREAD_QUERY_INFORMATION 64
+#define THREAD_SET_THREAD_TOKEN 128
+#define THREAD_IMPERSONATE 256
+#define THREAD_DIRECT_IMPERSONATION 0x200
+#define THREAD_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3FF)
+#define MUTANT_QUERY_STATE 0x0001
+#define MUTANT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|MUTANT_QUERY_STATE)
+#define TIMER_QUERY_STATE 0x0001
+#define TIMER_MODIFY_STATE 0x0002
+#define TIMER_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|TIMER_QUERY_STATE|TIMER_MODIFY_STATE)
+#define THREAD_BASE_PRIORITY_LOWRT 15
+#define THREAD_BASE_PRIORITY_MAX 2
+#define THREAD_BASE_PRIORITY_MIN (-2)
+#define THREAD_BASE_PRIORITY_IDLE (-15)
+/*
+ * To prevent gcc compiler warnings, bracket these defines when initialising
+ * a SID_IDENTIFIER_AUTHORITY, eg.
+ * SID_IDENTIFIER_AUTHORITY aNullSidAuthority = {SECURITY_NULL_SID_AUTHORITY};
+ */
+#define SID_MAX_SUB_AUTHORITIES 15
+
+/* security entities */
+#define SECURITY_NULL_RID (0x00000000L)
+#define SECURITY_WORLD_RID (0x00000000L)
+#define SECURITY_LOCAL_RID (0X00000000L)
+
+#define SECURITY_NULL_SID_AUTHORITY {0,0,0,0,0,0}
+
+/* S-1-1 */
+#define SECURITY_WORLD_SID_AUTHORITY {0,0,0,0,0,1}
+
+/* S-1-2 */
+#define SECURITY_LOCAL_SID_AUTHORITY {0,0,0,0,0,2}
+
+/* S-1-3 */
+#define SECURITY_CREATOR_SID_AUTHORITY {0,0,0,0,0,3}
+#define SECURITY_CREATOR_OWNER_RID (0x00000000L)
+#define SECURITY_CREATOR_GROUP_RID (0x00000001L)
+#define SECURITY_CREATOR_OWNER_SERVER_RID (0x00000002L)
+#define SECURITY_CREATOR_GROUP_SERVER_RID (0x00000003L)
+
+/* S-1-4 */
+#define SECURITY_NON_UNIQUE_AUTHORITY {0,0,0,0,0,4}
+
+/* S-1-5 */
+#define SECURITY_NT_AUTHORITY {0,0,0,0,0,5}
+#define SECURITY_DIALUP_RID 0x00000001L
+#define SECURITY_NETWORK_RID 0x00000002L
+#define SECURITY_BATCH_RID 0x00000003L
+#define SECURITY_INTERACTIVE_RID 0x00000004L
+#define SECURITY_LOGON_IDS_RID 0x00000005L
+#define SECURITY_SERVICE_RID 0x00000006L
+#define SECURITY_ANONYMOUS_LOGON_RID 0x00000007L
+#define SECURITY_PROXY_RID 0x00000008L
+#define SECURITY_ENTERPRISE_CONTROLLERS_RID 0x00000009L
+#define SECURITY_SERVER_LOGON_RID SECURITY_ENTERPRISE_CONTROLLERS_RID
+#define SECURITY_PRINCIPAL_SELF_RID 0x0000000AL
+#define SECURITY_AUTHENTICATED_USER_RID 0x0000000BL
+#define SECURITY_RESTRICTED_CODE_RID 0x0000000CL
+#define SECURITY_TERMINAL_SERVER_RID 0x0000000DL
+#define SECURITY_REMOTE_LOGON_RID 0x0000000EL
+#define SECURITY_THIS_ORGANIZATION_RID 0x0000000FL
+#define SECURITY_LOCAL_SYSTEM_RID 0x00000012L
+#define SECURITY_LOCAL_SERVICE_RID 0x00000013L
+#define SECURITY_NETWORK_SERVICE_RID 0x00000014L
+#define SECURITY_NT_NON_UNIQUE 0x00000015L
+#define SECURITY_BUILTIN_DOMAIN_RID 0x00000020L
+
+#define SECURITY_PACKAGE_BASE_RID 0x00000040L
+#define SECURITY_PACKAGE_NTLM_RID 0x0000000AL
+#define SECURITY_PACKAGE_SCHANNEL_RID 0x0000000EL
+#define SECURITY_PACKAGE_DIGEST_RID 0x00000015L
+#define SECURITY_OTHER_ORGANIZATION_RID 0x000003E8L
+
+#define SECURITY_LOGON_IDS_RID_COUNT 0x3
+#define SID_REVISION 1
+
+#define FOREST_USER_RID_MAX 0x000001F3L
+#define DOMAIN_USER_RID_ADMIN 0x000001F4L
+#define DOMAIN_USER_RID_GUEST 0x000001F5L
+#define DOMAIN_USER_RID_KRBTGT 0x000001F6L
+#define DOMAIN_USER_RID_MAX 0x000003E7L
+
+#define DOMAIN_GROUP_RID_ADMINS 0x00000200L
+#define DOMAIN_GROUP_RID_USERS 0x00000201L
+#define DOMAIN_GROUP_RID_GUESTS 0x00000202L
+#define DOMAIN_GROUP_RID_COMPUTERS 0x00000203L
+#define DOMAIN_GROUP_RID_CONTROLLERS 0x00000204L
+#define DOMAIN_GROUP_RID_CERT_ADMINS 0x00000205L
+#define DOMAIN_GROUP_RID_SCHEMA_ADMINS 0x00000206L
+#define DOMAIN_GROUP_RID_ENTERPRISE_ADMINS 0x00000207L
+#define DOMAIN_GROUP_RID_POLICY_ADMINS 0x00000208L
+
+#define SECURITY_MANDATORY_LABEL_AUTHORITY {0,0,0,0,0,16}
+#define SECURITY_MANDATORY_UNTRUSTED_RID 0x00000000L
+#define SECURITY_MANDATORY_LOW_RID 0x00001000L
+#define SECURITY_MANDATORY_MEDIUM_RID 0x00002000L
+#define SECURITY_MANDATORY_HIGH_RID 0x00003000L
+#define SECURITY_MANDATORY_SYSTEM_RID 0x00004000L
+#define SECURITY_MANDATORY_PROTECTED_PROCESS_RID 0x00005000L
+
+#define DOMAIN_ALIAS_RID_ADMINS 0x00000220L
+#define DOMAIN_ALIAS_RID_USERS 0x00000221L
+#define DOMAIN_ALIAS_RID_GUESTS 0x00000222L
+#define DOMAIN_ALIAS_RID_POWER_USERS 0x00000223L
+
+#define DOMAIN_ALIAS_RID_ACCOUNT_OPS 0x00000224L
+#define DOMAIN_ALIAS_RID_SYSTEM_OPS 0x00000225L
+#define DOMAIN_ALIAS_RID_PRINT_OPS 0x00000226L
+#define DOMAIN_ALIAS_RID_BACKUP_OPS 0x00000227L
+
+#define DOMAIN_ALIAS_RID_REPLICATOR 0x00000228L
+#define DOMAIN_ALIAS_RID_RAS_SERVERS 0x00000229L
+#define DOMAIN_ALIAS_RID_PREW2KCOMPACCESS 0x0000022AL
+#define DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS 0x0000022BL
+#define DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS 0x0000022CL
+#define DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS 0x0000022DL
+
+#define DOMAIN_ALIAS_RID_MONITORING_USERS 0x0000022EL
+#define DOMAIN_ALIAS_RID_LOGGING_USERS 0x0000022FL
+#define DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS 0x00000230L
+#define DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS 0x00000231L
+#define DOMAIN_ALIAS_RID_DCOM_USERS 0x00000232L
+
+#define SECURITY_MANDATORY_LABEL_AUTHORITY {0,0,0,0,0,16}
+
+typedef enum {
+ WinNullSid = 0,
+ WinWorldSid = 1,
+ WinLocalSid = 2,
+ WinCreatorOwnerSid = 3,
+ WinCreatorGroupSid = 4,
+ WinCreatorOwnerServerSid = 5,
+ WinCreatorGroupServerSid = 6,
+ WinNtAuthoritySid = 7,
+ WinDialupSid = 8,
+ WinNetworkSid = 9,
+ WinBatchSid = 10,
+ WinInteractiveSid = 11,
+ WinServiceSid = 12,
+ WinAnonymousSid = 13,
+ WinProxySid = 14,
+ WinEnterpriseControllersSid = 15,
+ WinSelfSid = 16,
+ WinAuthenticatedUserSid = 17,
+ WinRestrictedCodeSid = 18,
+ WinTerminalServerSid = 19,
+ WinRemoteLogonIdSid = 20,
+ WinLogonIdsSid = 21,
+ WinLocalSystemSid = 22,
+ WinLocalServiceSid = 23,
+ WinNetworkServiceSid = 24,
+ WinBuiltinDomainSid = 25,
+ WinBuiltinAdministratorsSid = 26,
+ WinBuiltinUsersSid = 27,
+ WinBuiltinGuestsSid = 28,
+ WinBuiltinPowerUsersSid = 29,
+ WinBuiltinAccountOperatorsSid = 30,
+ WinBuiltinSystemOperatorsSid = 31,
+ WinBuiltinPrintOperatorsSid = 32,
+ WinBuiltinBackupOperatorsSid = 33,
+ WinBuiltinReplicatorSid = 34,
+ WinBuiltinPreWindows2000CompatibleAccessSid = 35,
+ WinBuiltinRemoteDesktopUsersSid = 36,
+ WinBuiltinNetworkConfigurationOperatorsSid = 37,
+ WinAccountAdministratorSid = 38,
+ WinAccountGuestSid = 39,
+ WinAccountKrbtgtSid = 40,
+ WinAccountDomainAdminsSid = 41,
+ WinAccountDomainUsersSid = 42,
+ WinAccountDomainGuestsSid = 43,
+ WinAccountComputersSid = 44,
+ WinAccountControllersSid = 45,
+ WinAccountCertAdminsSid = 46,
+ WinAccountSchemaAdminsSid = 47,
+ WinAccountEnterpriseAdminsSid = 48,
+ WinAccountPolicyAdminsSid = 49,
+ WinAccountRasAndIasServersSid = 50,
+ WinNTLMAuthenticationSid = 51,
+ WinDigestAuthenticationSid = 52,
+ WinSChannelAuthenticationSid = 53,
+ WinThisOrganizationSid = 54,
+ WinOtherOrganizationSid = 55,
+ WinBuiltinIncomingForestTrustBuildersSid = 56,
+ WinBuiltinPerfMonitoringUsersSid = 57,
+ WinBuiltinPerfLoggingUsersSid = 58,
+ WinBuiltinAuthorizationAccessSid = 59,
+ WinBuiltinTerminalServerLicenseServersSid = 60,
+ WinBuiltinDCOMUsersSid = 61,
+ WinBuiltinIUsersSid = 62,
+ WinIUserSid = 63,
+ WinBuiltinCryptoOperatorsSid = 64,
+ WinUntrustedLabelSid = 65,
+ WinLowLabelSid = 66,
+ WinMediumLabelSid = 67,
+ WinHighLabelSid = 68,
+ WinSystemLabelSid = 69,
+ WinWriteRestrictedCodeSid = 70,
+ WinCreatorOwnerRightsSid = 71,
+ WinCacheablePrincipalsGroupSid = 72,
+ WinNonCacheablePrincipalsGroupSid = 73,
+ WinEnterpriseReadonlyControllersSid = 74,
+ WinAccountReadonlyControllersSid = 75,
+ WinBuiltinEventLogReadersGroup = 76,
+ WinNewEnterpriseReadonlyControllersSid = 77,
+ WinBuiltinCertSvcDComAccessGroup = 78,
+ WinMediumPlusLabelSid = 79,
+ WinLocalLogonSid = 80,
+ WinConsoleLogonSid = 81,
+ WinThisOrganizationCertificateSid = 82,
+} WELL_KNOWN_SID_TYPE;
+
+#define SE_CREATE_TOKEN_NAME TEXT("SeCreateTokenPrivilege")
+#define SE_ASSIGNPRIMARYTOKEN_NAME TEXT("SeAssignPrimaryTokenPrivilege")
+#define SE_LOCK_MEMORY_NAME TEXT("SeLockMemoryPrivilege")
+#define SE_INCREASE_QUOTA_NAME TEXT("SeIncreaseQuotaPrivilege")
+#define SE_UNSOLICITED_INPUT_NAME TEXT("SeUnsolicitedInputPrivilege")
+#define SE_MACHINE_ACCOUNT_NAME TEXT("SeMachineAccountPrivilege")
+#define SE_TCB_NAME TEXT("SeTcbPrivilege")
+#define SE_SECURITY_NAME TEXT("SeSecurityPrivilege")
+#define SE_TAKE_OWNERSHIP_NAME TEXT("SeTakeOwnershipPrivilege")
+#define SE_LOAD_DRIVER_NAME TEXT("SeLoadDriverPrivilege")
+#define SE_SYSTEM_PROFILE_NAME TEXT("SeSystemProfilePrivilege")
+#define SE_SYSTEMTIME_NAME TEXT("SeSystemtimePrivilege")
+#define SE_PROF_SINGLE_PROCESS_NAME TEXT("SeProfileSingleProcessPrivilege")
+#define SE_INC_BASE_PRIORITY_NAME TEXT("SeIncreaseBasePriorityPrivilege")
+#define SE_CREATE_PAGEFILE_NAME TEXT("SeCreatePagefilePrivilege")
+#define SE_CREATE_PERMANENT_NAME TEXT("SeCreatePermanentPrivilege")
+#define SE_BACKUP_NAME TEXT("SeBackupPrivilege")
+#define SE_RESTORE_NAME TEXT("SeRestorePrivilege")
+#define SE_SHUTDOWN_NAME TEXT("SeShutdownPrivilege")
+#define SE_DEBUG_NAME TEXT("SeDebugPrivilege")
+#define SE_AUDIT_NAME TEXT("SeAuditPrivilege")
+#define SE_SYSTEM_ENVIRONMENT_NAME TEXT("SeSystemEnvironmentPrivilege")
+#define SE_CHANGE_NOTIFY_NAME TEXT("SeChangeNotifyPrivilege")
+#define SE_REMOTE_SHUTDOWN_NAME TEXT("SeRemoteShutdownPrivilege")
+#define SE_UNDOCK_NAME TEXT("SeUndockPrivilege")
+#define SE_SYNC_AGENT_NAME TEXT("SeSyncAgentPrivilege")
+#define SE_ENABLE_DELEGATION_NAME TEXT("SeEnableDelegationPrivilege")
+#define SE_MANAGE_VOLUME_NAME TEXT("SeManageVolumePrivilege")
+#define SE_IMPERSONATE_NAME TEXT("SeImpersonatePrivilege")
+#define SE_CREATE_GLOBAL_NAME TEXT("SeCreateGlobalPrivilege")
+#define SE_GROUP_MANDATORY 1
+#define SE_GROUP_ENABLED_BY_DEFAULT 2
+#define SE_GROUP_ENABLED 4
+#define SE_GROUP_OWNER 8
+#define SE_GROUP_USE_FOR_DENY_ONLY 16
+#define SE_GROUP_LOGON_ID 3221225472U
+#define SE_GROUP_RESOURCE 536870912
+#define LANG_NEUTRAL 0x00
+#define LANG_INVARIANT 0x7f
+#define LANG_AFRIKAANS 0x36
+#define LANG_ALBANIAN 0x1c
+#define LANG_ALSATIAN 0x84
+#define LANG_AMHARIC 0x5e
+#define LANG_ARABIC 0x01
+#define LANG_ARMENIAN 0x2b
+#define LANG_ASSAMESE 0x4d
+#define LANG_AZERI 0x2c
+#define LANG_BASHKIR 0x6d
+#define LANG_BASQUE 0x2d
+#define LANG_BELARUSIAN 0x23
+#define LANG_BENGALI 0x45
+#define LANG_BOSNIAN 0x1a
+#define LANG_BRETON 0x7e
+#define LANG_BULGARIAN 0x02
+#define LANG_CATALAN 0x03
+#define LANG_CHINESE 0x04
+#define LANG_CHINESE_SIMPLIFIED 0x04
+#define LANG_CORSICAN 0x83
+#define LANG_CROATIAN 0x1a
+#define LANG_CROATIAN 0x1a
+#define LANG_CZECH 0x05
+#define LANG_DANISH 0x06
+#define LANG_DARI 0x8c
+#define LANG_DIVEHI 0x65
+#define LANG_DUTCH 0x13
+#define LANG_ENGLISH 0x09
+#define LANG_ESTONIAN 0x25
+#define LANG_FAEROESE 0x38
+#define LANG_FILIPINO 0x64
+#define LANG_FINNISH 0x0b
+#define LANG_FRENCH 0x0c
+#define LANG_FRISIAN 0x62
+#define LANG_GALICIAN 0x56
+#define LANG_GEORGIAN 0x37
+#define LANG_GERMAN 0x07
+#define LANG_GREEK 0x08
+#define LANG_GREENLANDIC 0x6f
+#define LANG_GUJARATI 0x47
+#define LANG_HAUSA 0x68
+#define LANG_HEBREW 0x0d
+#define LANG_HINDI 0x39
+#define LANG_HUNGARIAN 0x0e
+#define LANG_ICELANDIC 0x0f
+#define LANG_IGBO 0x70
+#define LANG_INDONESIAN 0x21
+#define LANG_INUKTITUT 0x5d
+#define LANG_IRISH 0x3c
+#define LANG_ITALIAN 0x10
+#define LANG_JAPANESE 0x11
+#define LANG_KANNADA 0x4b
+#define LANG_KASHMIRI 0x60
+#define LANG_KAZAK 0x3f
+#define LANG_KHMER 0x53
+#define LANG_KICHE 0x86
+#define LANG_KINYARWANDA 0x87
+#define LANG_KONKANI 0x57
+#define LANG_KOREAN 0x12
+#define LANG_KYRGYZ 0x40
+#define LANG_LAO 0x54
+#define LANG_LATVIAN 0x26
+#define LANG_LITHUANIAN 0x27
+#define LANG_LOWER_SORBIAN 0x2e
+#define LANG_LUXEMBOURGISH 0x6e
+#define LANG_MACEDONIAN 0x2f
+#define LANG_MALAY 0x3e
+#define LANG_MALAYALAM 0x4c
+#define LANG_MALTESE 0x3a
+#define LANG_MANIPURI 0x58
+#define LANG_MAORI 0x81
+#define LANG_MAPUDUNGUN 0x7a
+#define LANG_MARATHI 0x4e
+#define LANG_MOHAWK 0x7c
+#define LANG_MONGOLIAN 0x50
+#define LANG_NEPALI 0x61
+#define LANG_NORWEGIAN 0x14
+#define LANG_OCCITAN 0x82
+#define LANG_ORIYA 0x48
+#define LANG_PASHTO 0x63
+#define LANG_FARSI 0x29
+#define LANG_POLISH 0x15
+#define LANG_PORTUGUESE 0x16
+#define LANG_PUNJABI 0x46
+#define LANG_QUECHUA 0x6b
+#define LANG_ROMANIAN 0x18
+#define LANG_ROMANSH 0x17
+#define LANG_RUSSIAN 0x19
+#define LANG_SAMI 0x3b
+#define LANG_SANSKRIT 0x4f
+#define LANG_SERBIAN 0x1a
+#define LANG_SOTHO 0x6c
+#define LANG_TSWANA 0x32
+#define LANG_SINDHI 0x59
+#define LANG_SINHALESE 0x5b
+#define LANG_SLOVAK 0x1b
+#define LANG_SLOVENIAN 0x24
+#define LANG_SPANISH 0x0a
+#define LANG_SWAHILI 0x41
+#define LANG_SWEDISH 0x1d
+#define LANG_SYRIAC 0x5a
+#define LANG_TAJIK 0x28
+#define LANG_TAMAZIGHT 0x5f
+#define LANG_TAMIL 0x49
+#define LANG_TATAR 0x44
+#define LANG_TELUGU 0x4a
+#define LANG_THAI 0x1e
+#define LANG_TIBETAN 0x51
+#define LANG_TIGRIGNA 0x73
+#define LANG_TURKISH 0x1f
+#define LANG_TURKMEN 0x42
+#define LANG_UIGHUR 0x80
+#define LANG_UKRAINIAN 0x22
+#define LANG_UPPER_SORBIAN 0x2e
+#define LANG_URDU 0x20
+#define LANG_UZBEK 0x43
+#define LANG_VIETNAMESE 0x2a
+#define LANG_WELSH 0x52
+#define LANG_WOLOF 0x88
+#define LANG_XHOSA 0x34
+#define LANG_YAKUT 0x85
+#define LANG_YI 0x78
+#define LANG_YORUBA 0x6a
+#define LANG_ZULU 0x35
+
+/* FIXME: non-standard */
+#define LANG_ESPERANTO 0x8f
+#define LANG_WALON 0x90
+#define LANG_CORNISH 0x91
+
+/* FIXME: not present in the official headers */
+#define LANG_GAELIC 0x94
+#define LANG_SAAMI 0x3b
+#define LANG_SUTU 0x30
+#define LANG_TSONGA 0x31
+#define LANG_VENDA 0x33
+
+#define SUBLANG_CUSTOM_UNSPECIFIED 0x04
+#define SUBLANG_CUSTOM_DEFAULT 0x03
+#define SUBLANG_UI_CUSTOM_DEFAULT 0x05
+#define SUBLANG_NEUTRAL 0x00
+#define SUBLANG_SYS_DEFAULT 0x02
+#define SUBLANG_DEFAULT 0x01
+#define SUBLANG_AFRIKAANS_SOUTH_AFRICA 0x01
+#define SUBLANG_ALBANIAN_ALBANIA 0x01
+#define SUBLANG_ALSATIAN_FRANCE 0x01
+#define SUBLANG_AMHARIC_ETHIOPIA 0x01
+#define SUBLANG_ARABIC_ALGERIA 0x05
+#define SUBLANG_ARABIC_BAHRAIN 0x0f
+#define SUBLANG_ARABIC_EGYPT 0x03
+#define SUBLANG_ARABIC_IRAQ 0x02
+#define SUBLANG_ARABIC_JORDAN 0x0b
+#define SUBLANG_ARABIC_KUWAIT 0x0d
+#define SUBLANG_ARABIC_LEBANON 0x0c
+#define SUBLANG_ARABIC_LIBYA 0x04
+#define SUBLANG_ARABIC_MOROCCO 0x06
+#define SUBLANG_ARABIC_OMAN 0x08
+#define SUBLANG_ARABIC_QATAR 0x10
+#define SUBLANG_ARABIC_SAUDI_ARABIA 0x01
+#define SUBLANG_ARABIC_SYRIA 0x0a
+#define SUBLANG_ARABIC_TUNISIA 0x07
+#define SUBLANG_ARABIC_UAE 0x0e
+#define SUBLANG_ARABIC_YEMEN 0x09
+#define SUBLANG_ARMENIAN_ARMENIA 0x01
+#define SUBLANG_ASSAMESE_INDIA 0x01
+#define SUBLANG_AZERI_CYRILLIC 0x02
+#define SUBLANG_AZERI_LATIN 0x01
+#define SUBLANG_BASHKIR_RUSSIA 0x01
+#define SUBLANG_BASQUE_BASQUE 0x01
+#define SUBLANG_BELARUSIAN_BELARUS 0x01
+#define SUBLANG_BENGALI_BANGLADESH 0x02
+#define SUBLANG_BENGALI_INDIA 0x01
+#define SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_CYRILLIC 0x08
+#define SUBLANG_BOSNIAN_BOSNIA_HERZEGOVINA_LATIN 0x05
+#define SUBLANG_BRETON_FRANCE 0x01
+#define SUBLANG_BULGARIAN_BULGARIA 0x01
+#define SUBLANG_CATALAN_CATALAN 0x01
+#define SUBLANG_CHINESE_HONGKONG 0x03
+#define SUBLANG_CHINESE_MACAU 0x05
+#define SUBLANG_CHINESE_SINGAPORE 0x04
+#define SUBLANG_CHINESE_SIMPLIFIED 0x02
+#define SUBLANG_CHINESE_TRADITIONAL 0x01
+#define SUBLANG_CORSICAN_FRANCE 0x01
+#define SUBLANG_CROATIAN_BOSNIA_HERZEGOVINA_LATIN 0x04
+#define SUBLANG_CROATIAN_CROATIA 0x01
+#define SUBLANG_CZECH_CZECH_REPUBLIC 0x01
+#define SUBLANG_DANISH_DENMARK 0x01
+#define SUBLANG_DARI_AFGHANISTAN 0x01
+#define SUBLANG_DIVEHI_MALDIVES 0x01
+#define SUBLANG_DUTCH_BELGIAN 0x02
+#define SUBLANG_DUTCH 0x01
+#define SUBLANG_ENGLISH_AUS 0x03
+#define SUBLANG_ENGLISH_BELIZE 0x0a
+#define SUBLANG_ENGLISH_CAN 0x04
+#define SUBLANG_ENGLISH_CARIBBEAN 0x09
+#define SUBLANG_ENGLISH_INDIA 0x10
+#define SUBLANG_ENGLISH_EIRE 0x06
+#define SUBLANG_ENGLISH_IRELAND 0x06
+#define SUBLANG_ENGLISH_JAMAICA 0x08
+#define SUBLANG_ENGLISH_MALAYSIA 0x11
+#define SUBLANG_ENGLISH_NZ 0x05
+#define SUBLANG_ENGLISH_PHILIPPINES 0x0d
+#define SUBLANG_ENGLISH_SINGAPORE 0x12
+#define SUBLANG_ENGLISH_SOUTH_AFRICA 0x07
+#define SUBLANG_ENGLISH_TRINIDAD 0x0b
+#define SUBLANG_ENGLISH_UK 0x02
+#define SUBLANG_ENGLISH_US 0x01
+#define SUBLANG_ENGLISH_ZIMBABWE 0x0c
+#define SUBLANG_ESTONIAN_ESTONIA 0x01
+#define SUBLANG_FAEROESE_FAROE_ISLANDS 0x01
+#define SUBLANG_FILIPINO_PHILIPPINES 0x01
+#define SUBLANG_FINNISH_FINLAND 0x01
+#define SUBLANG_FRENCH_BELGIAN 0x02
+#define SUBLANG_FRENCH_CANADIAN 0x03
+#define SUBLANG_FRENCH 0x01
+#define SUBLANG_FRENCH_LUXEMBOURG 0x05
+#define SUBLANG_FRENCH_MONACO 0x06
+#define SUBLANG_FRENCH_SWISS 0x04
+#define SUBLANG_FRISIAN_NETHERLANDS 0x01
+#define SUBLANG_GALICIAN_GALICIAN 0x01
+#define SUBLANG_GEORGIAN_GEORGIA 0x01
+#define SUBLANG_GERMAN_AUSTRIAN 0x03
+#define SUBLANG_GERMAN 0x01
+#define SUBLANG_GERMAN_LIECHTENSTEIN 0x05
+#define SUBLANG_GERMAN_LUXEMBOURG 0x04
+#define SUBLANG_GERMAN_SWISS 0x02
+#define SUBLANG_GREEK_GREECE 0x01
+#define SUBLANG_GREENLANDIC_GREENLAND 0x01
+#define SUBLANG_GUJARATI_INDIA 0x01
+#define SUBLANG_HAUSA_NIGERIA_LATIN 0x01
+#define SUBLANG_HAUSA_NIGERIA 0x01
+#define SUBLANG_HEBREW_ISRAEL 0x01
+#define SUBLANG_HINDI_INDIA 0x01
+#define SUBLANG_HUNGARIAN_HUNGARY 0x01
+#define SUBLANG_ICELANDIC_ICELAND 0x01
+#define SUBLANG_IGBO_NIGERIA 0x01
+#define SUBLANG_INDONESIAN_INDONESIA 0x01
+#define SUBLANG_INUKTITUT_CANADA_LATIN 0x02
+#define SUBLANG_INUKTITUT_CANADA 0x01
+#define SUBLANG_IRISH_IRELAND 0x02
+#define SUBLANG_ITALIAN 0x01
+#define SUBLANG_ITALIAN_SWISS 0x02
+#define SUBLANG_JAPANESE_JAPAN 0x01
+#define SUBLANG_KANNADA_INDIA 0x01
+#define SUBLANG_KASHMIRI_INDIA 0x02
+#define SUBLANG_KASHMIRI_SASIA 0x02
+#define SUBLANG_KAZAK_KAZAKHSTAN 0x01
+#define SUBLANG_KHMER_CAMBODIA 0x01
+#define SUBLANG_KICHE_GUATEMALA 0x01
+#define SUBLANG_KINYARWANDA_RWANDA 0x01
+#define SUBLANG_KONKANI_INDIA 0x01
+#define SUBLANG_KOREAN 0x01
+#define SUBLANG_KYRGYZ_KYRGYZSTAN 0x01
+#define SUBLANG_LAO_LAO 0x01
+#define SUBLANG_LAO_LAO_PDR 0x01
+#define SUBLANG_LATVIAN_LATVIA 0x01
+#define SUBLANG_LITHUANIAN_LITHUANIA 0x01
+#define SUBLANG_LITHUANIAN 0x01
+#define SUBLANG_LOWER_SORBIAN_GERMANY 0x02
+#define SUBLANG_LUXEMBOURGISH_LUXEMBOURG 0x01
+#define SUBLANG_MACEDONIAN_MACEDONIA 0x01
+#define SUBLANG_MALAY_BRUNEI_DARUSSALAM 0x02
+#define SUBLANG_MALAY_MALAYSIA 0x01
+#define SUBLANG_MALAYALAM_INDIA 0x01
+#define SUBLANG_MALTESE_MALTA 0x01
+#define SUBLANG_MAORI_NEW_ZEALAND 0x01
+#define SUBLANG_MAPUDUNGUN_CHILE 0x01
+#define SUBLANG_MARATHI_INDIA 0x01
+#define SUBLANG_MOHAWK_MOHAWK 0x01
+#define SUBLANG_MONGOLIAN_CYRILLIC_MONGOLIA 0x01
+#define SUBLANG_MONGOLIAN_PRC 0x02
+#define SUBLANG_NEPALI_NEPAL 0x01
+#define SUBLANG_NEPALI_INDIA 0x02
+#define SUBLANG_NORWEGIAN_BOKMAL 0x01
+#define SUBLANG_NORWEGIAN_NYNORSK 0x02
+#define SUBLANG_OCCITAN_FRANCE 0x01
+#define SUBLANG_ORIYA_INDIA 0x01
+#define SUBLANG_PASHTO_AFGHANISTAN 0x01
+#define SUBLANG_PERSIAN_IRAN 0x01
+#define SUBLANG_POLISH_POLAND 0x01
+#define SUBLANG_PORTUGUESE_BRAZILIAN 0x01
+#define SUBLANG_PORTUGUESE 0x02
+#define SUBLANG_PORTUGUESE_PORTUGAL 0x02
+#define SUBLANG_PUNJABI_INDIA 0x01
+#define SUBLANG_QUECHUA_BOLIVIA 0x01
+#define SUBLANG_QUECHUA_ECUADOR 0x02
+#define SUBLANG_QUECHUA_PERU 0x03
+#define SUBLANG_ROMANIAN_ROMANIA 0x01
+#define SUBLANG_ROMANSH_SWITZERLAND 0x01
+#define SUBLANG_RUSSIAN_RUSSIA 0x01
+#define SUBLANG_SAMI_INARI_FINLAND 0x09
+#define SUBLANG_SAMI_LULE_NORWAY 0x04
+#define SUBLANG_SAMI_LULE_SWEDEN 0x05
+#define SUBLANG_SAMI_NORTHERN_FINLAND 0x03
+#define SUBLANG_SAMI_NORTHERN_NORWAY 0x01
+#define SUBLANG_SAMI_NORTHERN_SWEDEN 0x02
+#define SUBLANG_SAMI_SKOLT_FINLAND 0x08
+#define SUBLANG_SAMI_SOUTHERN_NORWAY 0x06
+#define SUBLANG_SAMI_SOUTHERN_SWEDEN 0x07
+#define SUBLANG_SANSKRIT_INDIA 0x01
+#define SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_CYRILLIC 0x07
+#define SUBLANG_SERBIAN_BOSNIA_HERZEGOVINA_LATIN 0x06
+#define SUBLANG_SERBIAN_CROATIA 0x01
+#define SUBLANG_SERBIAN_CYRILLIC 0x03
+#define SUBLANG_SERBIAN_LATIN 0x02
+#define SUBLANG_SOTHO_NORTHERN_SOUTH_AFRICA 0x01
+#define SUBLANG_TSWANA_SOUTH_AFRICA 0x01
+#define SUBLANG_SINDHI_AFGHANISTAN 0x02
+#define SUBLANG_SINDHI_PAKISTAN 0x01
+#define SUBLANG_SINHALESE_SRI_LANKA 0x01
+#define SUBLANG_SLOVAK_SLOVAKIA 0x01
+#define SUBLANG_SLOVENIAN_SLOVENIA 0x01
+#define SUBLANG_SPANISH_ARGENTINA 0x0b
+#define SUBLANG_SPANISH_BOLIVIA 0x10
+#define SUBLANG_SPANISH_CHILE 0x0d
+#define SUBLANG_SPANISH_COLOMBIA 0x09
+#define SUBLANG_SPANISH_COSTA_RICA 0x05
+#define SUBLANG_SPANISH_DOMINICAN_REPUBLIC 0x07
+#define SUBLANG_SPANISH_ECUADOR 0x0c
+#define SUBLANG_SPANISH_EL_SALVADOR 0x11
+#define SUBLANG_SPANISH_GUATEMALA 0x04
+#define SUBLANG_SPANISH_HONDURAS 0x12
+#define SUBLANG_SPANISH_MEXICAN 0x02
+#define SUBLANG_SPANISH_MODERN 0x03
+#define SUBLANG_SPANISH_NICARAGUA 0x13
+#define SUBLANG_SPANISH_PANAMA 0x06
+#define SUBLANG_SPANISH_PARAGUAY 0x0f
+#define SUBLANG_SPANISH_PERU 0x0a
+#define SUBLANG_SPANISH_PUERTO_RICO 0x14
+#define SUBLANG_SPANISH 0x01
+#define SUBLANG_SPANISH_US 0x15
+#define SUBLANG_SPANISH_URUGUAY 0x0e
+#define SUBLANG_SPANISH_VENEZUELA 0x08
+#define SUBLANG_SWAHILI 0x01
+#define SUBLANG_SWAHILI_KENYA 0x01
+#define SUBLANG_SWEDISH_FINLAND 0x02
+#define SUBLANG_SWEDISH 0x01
+#define SUBLANG_SWEDISH_SWEDEN 0x01
+#define SUBLANG_SYRIAC 0x01
+#define SUBLANG_TAJIK_TAJIKISTAN 0x01
+#define SUBLANG_TAMAZIGHT_ALGERIA_LATIN 0x02
+#define SUBLANG_TAMIL_INDIA 0x01
+#define SUBLANG_TATAR_RUSSIA 0x01
+#define SUBLANG_TELUGU_INDIA 0x01
+#define SUBLANG_THAI_THAILAND 0x01
+#define SUBLANG_TIBETAN_PRC 0x01
+#define SUBLANG_TIGRIGNA_ERITREA 0x02
+#define SUBLANG_TURKISH_TURKEY 0x01
+#define SUBLANG_TURKMEN_TURKMENISTAN 0x01
+#define SUBLANG_UIGHUR_PRC 0x01
+#define SUBLANG_UKRAINIAN_UKRAINE 0x01
+#define SUBLANG_UPPER_SORBIAN_GERMANY 0x01
+#define SUBLANG_URDU_INDIA 0x02
+#define SUBLANG_URDU_PAKISTAN 0x01
+#define SUBLANG_UZBEK_CYRILLIC 0x02
+#define SUBLANG_UZBEK_LATIN 0x01
+#define SUBLANG_VIETNAMESE_VIETNAM 0x01
+#define SUBLANG_WELSH_UNITED_KINGDOM 0x01
+#define SUBLANG_WOLOF_SENEGAL 0x01
+#define SUBLANG_XHOSA_SOUTH_AFRICA 0x01
+#define SUBLANG_YAKUT_RUSSIA 0x01
+#define SUBLANG_YI_PRC 0x01
+#define SUBLANG_YORUBA_NIGERIA 0x01
+#define SUBLANG_ZULU_SOUTH_AFRICA 0x01
+#define NLS_VALID_LOCALE_MASK 1048575
+#define SORT_DEFAULT 0
+#define SORT_JAPANESE_XJIS 0
+#define SORT_JAPANESE_UNICODE 1
+#define SORT_CHINESE_BIG5 0
+#define SORT_CHINESE_PRCP 0
+#define SORT_CHINESE_UNICODE 1
+#define SORT_CHINESE_PRC 2
+#define SORT_CHINESE_BOPOMOFO 3
+#define SORT_KOREAN_KSC 0
+#define SORT_KOREAN_UNICODE 1
+#define SORT_GERMAN_PHONE_BOOK 1
+#define SORT_HUNGARIAN_DEFAULT 0
+#define SORT_HUNGARIAN_TECHNICAL 1
+#define SORT_GEORGIAN_TRADITIONAL 0
+#define SORT_GEORGIAN_MODERN 1
+#define MAKELANGID(p,s) ((((WORD)(s))<<10)|(WORD)(p))
+#define MAKELCID(l,s) ((DWORD)((((DWORD)((WORD)(s)))<<16)|((DWORD)((WORD)(l)))))
+#define PRIMARYLANGID(l) ((WORD)(l)&0x3ff)
+#define SORTIDFROMLCID(l) ((WORD)((((DWORD)(l))&NLS_VALID_LOCALE_MASK)>>16))
+#define SORTVERSIONFROMLCID(l) ((WORD)((((DWORD)(l))>>20)&0xf))
+#define SUBLANGID(l) ((WORD)(l)>>10)
+#define LANGIDFROMLCID(l) ((WORD)(l))
+#define LANG_SYSTEM_DEFAULT MAKELANGID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT)
+#define LANG_USER_DEFAULT MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT)
+#define LOCALE_NEUTRAL MAKELCID(MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),SORT_DEFAULT)
+#define LOCALE_INVARIANT MAKELCID(MAKELANGID(LANG_INVARIANT, SUBLANG_NEUTRAL), SORT_DEFAULT)
+#define ACL_REVISION 2
+#define ACL_REVISION_DS 4
+#define ACL_REVISION1 1
+#define ACL_REVISION2 2
+#define ACL_REVISION3 3
+#define ACL_REVISION4 4
+#define MIN_ACL_REVISION 2
+#define MAX_ACL_REVISION 4
+#define MINCHAR 0x80
+#define MAXCHAR 0x7f
+#define MINSHORT 0x8000
+#define MAXSHORT 0x7fff
+#define MINLONG 0x80000000
+#define MAXLONG 0x7fffffff
+#define MAXBYTE 0xff
+#define MAXWORD 0xffff
+#define MAXDWORD 0xffffffff
+#define PROCESSOR_INTEL_386 386
+#define PROCESSOR_INTEL_486 486
+#define PROCESSOR_INTEL_PENTIUM 586
+#define PROCESSOR_MIPS_R4000 4000
+#define PROCESSOR_ALPHA_21064 21064
+#define PROCESSOR_INTEL_IA64 2200
+#define PROCESSOR_PPC_601 601
+#define PROCESSOR_PPC_603 603
+#define PROCESSOR_PPC_604 604
+#define PROCESSOR_PPC_620 620
+#define PROCESSOR_INTEL_860 860
+#define PROCESSOR_AMD_X8664 8664
+#define PROCESSOR_MIPS_R2000 2000
+#define PROCESSOR_MIPS_R3000 3000
+#define PROCESSOR_HITACHI_SH3 10003
+#define PROCESSOR_HITACHI_SH3E 10004
+#define PROCESSOR_HITACHI_SH4 10005
+#define PROCESSOR_MOTOROLA_821 821
+#define PROCESSOR_SHx_SH3 103
+#define PROCESSOR_SHx_SH4 104
+#define PROCESSOR_STRONGARM 2577
+#define PROCESSOR_ARM720 1824
+#define PROCESSOR_ARM820 2080
+#define PROCESSOR_ARM920 2336
+#define PROCESSOR_ARM_7TDMI 70001
+#define PROCESSOR_ARCHITECTURE_INTEL 0
+#define PROCESSOR_ARCHITECTURE_MIPS 1
+#define PROCESSOR_ARCHITECTURE_ALPHA 2
+#define PROCESSOR_ARCHITECTURE_PPC 3
+#define PROCESSOR_ARCHITECTURE_SHX 4
+#define PROCESSOR_ARCHITECTURE_ARM 5
+#define PROCESSOR_ARCHITECTURE_IA64 6
+#define PROCESSOR_ARCHITECTURE_ALPHA64 7
+#define PROCESSOR_ARCHITECTURE_MSIL 8
+#define PROCESSOR_ARCHITECTURE_AMD64 9
+#define PROCESSOR_ARCHITECTURE_UNKNOWN 0xFFFF
+#define PF_FLOATING_POINT_PRECISION_ERRATA 0
+#define PF_FLOATING_POINT_EMULATED 1
+#define PF_COMPARE_EXCHANGE_DOUBLE 2
+#define PF_MMX_INSTRUCTIONS_AVAILABLE 3
+#define PF_PPC_MOVEMEM_64BIT_OK 4
+#define PF_ALPHA_BYTE_INSTRUCTIONS 5
+#define PF_XMMI_INSTRUCTIONS_AVAILABLE 6
+#define PF_3DNOW_INSTRUCTIONS_AVAILABLE 7
+#define PF_RDTSC_INSTRUCTION_AVAILABLE 8
+#define PF_PAE_ENABLED 9
+#define PF_XMMI64_INSTRUCTIONS_AVAILABLE 10
+/* also in ddk/ntifs.h */
+#define FILE_ACTION_ADDED 0x00000001
+#define FILE_ACTION_REMOVED 0x00000002
+#define FILE_ACTION_MODIFIED 0x00000003
+#define FILE_ACTION_RENAMED_OLD_NAME 0x00000004
+#define FILE_ACTION_RENAMED_NEW_NAME 0x00000005
+#define FILE_ACTION_ADDED_STREAM 0x00000006
+#define FILE_ACTION_REMOVED_STREAM 0x00000007
+#define FILE_ACTION_MODIFIED_STREAM 0x00000008
+#define FILE_ACTION_REMOVED_BY_DELETE 0x00000009
+#define FILE_ACTION_ID_NOT_TUNNELLED 0x0000000A
+#define FILE_ACTION_TUNNELLED_ID_COLLISION 0x0000000B
+/* end ntifs.h */
+#define HEAP_NO_SERIALIZE 1
+#define HEAP_GROWABLE 2
+#define HEAP_GENERATE_EXCEPTIONS 4
+#define HEAP_ZERO_MEMORY 8
+#define HEAP_REALLOC_IN_PLACE_ONLY 16
+#define HEAP_TAIL_CHECKING_ENABLED 32
+#define HEAP_FREE_CHECKING_ENABLED 64
+#define HEAP_DISABLE_COALESCE_ON_FREE 128
+#define HEAP_CREATE_ALIGN_16 0x10000
+#define HEAP_CREATE_ENABLE_TRACING 0x20000
+#define HEAP_CREATE_ENABLE_EXECUTE 0x00040000
+#define HEAP_MAXIMUM_TAG 0xFFF
+#define HEAP_PSEUDO_TAG_FLAG 0x8000
+#define HEAP_TAG_SHIFT 16
+#define HEAP_MAKE_TAG_FLAGS(b,o) ((DWORD)((b)+(o)<<16)))
+
+#define KEY_QUERY_VALUE 1
+#define KEY_SET_VALUE 2
+#define KEY_CREATE_SUB_KEY 4
+#define KEY_ENUMERATE_SUB_KEYS 8
+#define KEY_NOTIFY 16
+#define KEY_CREATE_LINK 32
+#define KEY_WOW64_64KEY 0x00000100
+#define KEY_WOW64_32KEY 0x00000200
+#define KEY_WOW64_RES 0x00000300
+
+#define KEY_WRITE 0x20006
+#define KEY_EXECUTE 0x20019
+#define KEY_READ 0x20019
+#define KEY_ALL_ACCESS 0xf003f
+#define REG_WHOLE_HIVE_VOLATILE 1
+#define REG_REFRESH_HIVE 2
+#define REG_NO_LAZY_FLUSH 4
+#define REG_OPTION_RESERVED 0
+#define REG_OPTION_NON_VOLATILE 0
+#define REG_OPTION_VOLATILE 1
+#define REG_OPTION_CREATE_LINK 2
+#define REG_OPTION_BACKUP_RESTORE 4
+#define REG_OPTION_OPEN_LINK 8
+#define REG_LEGAL_OPTION 15
+#define OWNER_SECURITY_INFORMATION 1
+#define GROUP_SECURITY_INFORMATION 2
+#define DACL_SECURITY_INFORMATION 4
+#define SACL_SECURITY_INFORMATION 8
+#define PROTECTED_DACL_SECURITY_INFORMATION 0x80000000
+#define PROTECTED_SACL_SECURITY_INFORMATION 0x40000000
+#define UNPROTECTED_DACL_SECURITY_INFORMATION 0x20000000
+#define UNPROTECTED_SACL_SECURITY_INFORMATION 0x10000000
+#define MAXIMUM_PROCESSORS 32
+#define PAGE_NOACCESS 0x0001
+#define PAGE_READONLY 0x0002
+#define PAGE_READWRITE 0x0004
+#define PAGE_WRITECOPY 0x0008
+#define PAGE_EXECUTE 0x0010
+#define PAGE_EXECUTE_READ 0x0020
+#define PAGE_EXECUTE_READWRITE 0x0040
+#define PAGE_EXECUTE_WRITECOPY 0x0080
+#define PAGE_GUARD 0x0100
+#define PAGE_NOCACHE 0x0200
+#define PAGE_WRITECOMBINE 0x0400
+#define MEM_COMMIT 0x1000
+#define MEM_RESERVE 0x2000
+#define MEM_DECOMMIT 0x4000
+#define MEM_RELEASE 0x8000
+#define MEM_FREE 0x10000
+#define MEM_PRIVATE 0x20000
+#define MEM_MAPPED 0x40000
+#define MEM_RESET 0x80000
+#define MEM_TOP_DOWN 0x100000
+#define MEM_WRITE_WATCH 0x200000 /* 98/Me */
+#define MEM_PHYSICAL 0x400000
+#define MEM_4MB_PAGES 0x80000000
+#define MEM_IMAGE SEC_IMAGE
+#define SEC_NO_CHANGE 0x00400000
+#define SEC_FILE 0x00800000
+#define SEC_IMAGE 0x01000000
+#define SEC_VLM 0x02000000
+#define SEC_RESERVE 0x04000000
+#define SEC_COMMIT 0x08000000
+#define SEC_NOCACHE 0x10000000
+#define SEC_WRITECOMBINE 0x40000000
+#define SEC_LARGE_PAGES 0x80000000
+#define SECTION_EXTEND_SIZE 16
+#define SECTION_MAP_READ 4
+#define SECTION_MAP_WRITE 2
+#define SECTION_QUERY 1
+#define SECTION_MAP_EXECUTE 8
+#define SECTION_ALL_ACCESS 0xf001f
+#define WRITE_WATCH_FLAG_RESET 0x01
+#define MESSAGE_RESOURCE_UNICODE 1
+#define RTL_CRITSECT_TYPE 0
+#define RTL_RESOURCE_TYPE 1
+/* Also in winddk.h */
+#if !defined(__GNUC__)
+#define FIELD_OFFSET(t,f) ((LONG)(LONG_PTR)&(((t*) 0)->f))
+#else
+#define FIELD_OFFSET(t,f) ((LONG)__builtin_offsetof(t,f))
+#endif
+#ifndef CONTAINING_RECORD
+#define CONTAINING_RECORD(address, type, field) \
+ ((type *)(((ULONG_PTR)address) - (ULONG_PTR)(&(((type *)0)->field))))
+#endif
+/* end winddk.h */
+#define IMAGE_SIZEOF_FILE_HEADER 20
+#define IMAGE_FILE_RELOCS_STRIPPED 1
+#define IMAGE_FILE_EXECUTABLE_IMAGE 2
+#define IMAGE_FILE_LINE_NUMS_STRIPPED 4
+#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 8
+#define IMAGE_FILE_AGGRESIVE_WS_TRIM 16
+#define IMAGE_FILE_LARGE_ADDRESS_AWARE 32
+#define IMAGE_FILE_BYTES_REVERSED_LO 128
+#define IMAGE_FILE_32BIT_MACHINE 256
+#define IMAGE_FILE_DEBUG_STRIPPED 512
+#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 1024
+#define IMAGE_FILE_NET_RUN_FROM_SWAP 2048
+#define IMAGE_FILE_SYSTEM 4096
+#define IMAGE_FILE_DLL 8192
+#define IMAGE_FILE_UP_SYSTEM_ONLY 16384
+#define IMAGE_FILE_BYTES_REVERSED_HI 32768
+#define IMAGE_FILE_MACHINE_UNKNOWN 0
+
+#define IMAGE_FILE_MACHINE_AM33 0x1d3
+#define IMAGE_FILE_MACHINE_AMD64 0x8664
+#define IMAGE_FILE_MACHINE_ARM 0x1c0
+#define IMAGE_FILE_MACHINE_EBC 0xebc
+#define IMAGE_FILE_MACHINE_I386 0x14c
+#define IMAGE_FILE_MACHINE_IA64 0x200
+#define IMAGE_FILE_MACHINE_M32R 0x9041
+#define IMAGE_FILE_MACHINE_MIPS16 0x266
+#define IMAGE_FILE_MACHINE_MIPSFPU 0x366
+#define IMAGE_FILE_MACHINE_MIPSFPU16 0x466
+#define IMAGE_FILE_MACHINE_POWERPC 0x1f0
+#define IMAGE_FILE_MACHINE_POWERPCFP 0x1f1
+#define IMAGE_FILE_MACHINE_R4000 0x166
+#define IMAGE_FILE_MACHINE_SH3 0x1a2
+#define IMAGE_FILE_MACHINE_SH3E 0x01a4
+#define IMAGE_FILE_MACHINE_SH3DSP 0x1a3
+#define IMAGE_FILE_MACHINE_SH4 0x1a6
+#define IMAGE_FILE_MACHINE_SH5 0x1a8
+#define IMAGE_FILE_MACHINE_THUMB 0x1c2
+#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x169
+#define IMAGE_FILE_MACHINE_R3000 0x162
+#define IMAGE_FILE_MACHINE_R10000 0x168
+#define IMAGE_FILE_MACHINE_ALPHA 0x184
+#define IMAGE_FILE_MACHINE_ALPHA64 0x0284
+#define IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64
+#define IMAGE_FILE_MACHINE_CEE 0xC0EE
+#define IMAGE_FILE_MACHINE_TRICORE 0x0520
+#define IMAGE_FILE_MACHINE_CEF 0x0CEF
+
+#define IMAGE_FILE_EXPORT_DIRECTORY 0
+#define IMAGE_FILE_IMPORT_DIRECTORY 1
+#define IMAGE_FILE_RESOURCE_DIRECTORY 2
+#define IMAGE_FILE_EXCEPTION_DIRECTORY 3
+#define IMAGE_FILE_SECURITY_DIRECTORY 4
+#define IMAGE_FILE_BASE_RELOCATION_TABLE 5
+#define IMAGE_FILE_DEBUG_DIRECTORY 6
+#define IMAGE_FILE_DESCRIPTION_STRING 7
+#define IMAGE_FILE_MACHINE_VALUE 8 /* Mips */
+#define IMAGE_FILE_THREAD_LOCAL_STORAGE 9
+#define IMAGE_FILE_CALLBACK_DIRECTORY 10
+
+#define IMAGE_DOS_SIGNATURE 0x5A4D
+#define IMAGE_OS2_SIGNATURE 0x454E
+#define IMAGE_OS2_SIGNATURE_LE 0x454C
+#define IMAGE_VXD_SIGNATURE 0x454C
+#define IMAGE_NT_SIGNATURE 0x00004550
+#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
+#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
+#ifdef _WIN64
+#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR64_MAGIC
+#else
+#define IMAGE_NT_OPTIONAL_HDR_MAGIC IMAGE_NT_OPTIONAL_HDR32_MAGIC
+#endif
+#define IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107
+#define IMAGE_SEPARATE_DEBUG_SIGNATURE 0x4944
+#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
+#define IMAGE_SIZEOF_ROM_OPTIONAL_HEADER 56
+#define IMAGE_SIZEOF_STD_OPTIONAL_HEADER 28
+#define IMAGE_SIZEOF_NT_OPTIONAL_HEADER 224
+#define IMAGE_SIZEOF_SHORT_NAME 8
+#define IMAGE_SIZEOF_SECTION_HEADER 40
+#define IMAGE_SIZEOF_SYMBOL 18
+#define IMAGE_SIZEOF_AUX_SYMBOL 18
+#define IMAGE_SIZEOF_RELOCATION 10
+#define IMAGE_SIZEOF_BASE_RELOCATION 8
+#define IMAGE_SIZEOF_LINENUMBER 6
+#define IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60
+#define SIZEOF_RFPO_DATA 16
+
+#define IMAGE_SUBSYSTEM_UNKNOWN 0
+#define IMAGE_SUBSYSTEM_NATIVE 1
+#define IMAGE_SUBSYSTEM_WINDOWS_GUI 2
+#define IMAGE_SUBSYSTEM_WINDOWS_CUI 3
+#define IMAGE_SUBSYSTEM_OS2_CUI 5
+#define IMAGE_SUBSYSTEM_POSIX_CUI 7
+#define IMAGE_SUBSYSTEM_NATIVE_WINDOWS 8
+#define IMAGE_SUBSYSTEM_WINDOWS_CE_GUI 9
+#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10
+#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11
+#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12
+#define IMAGE_SUBSYSTEM_EFI_ROM 13
+#define IMAGE_SUBSYSTEM_XBOX 14
+
+#define IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE 0x0040
+#define IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY 0x0080
+#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x0100
+#define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION 0x0200
+#define IMAGE_DLLCHARACTERISTICS_NO_SEH 0x0400
+#define IMAGE_DLLCHARACTERISTICS_NO_BIND 0x0800
+#define IMAGE_DLLCHARACTERISTICS_WDM_DRIVER 0x2000
+#define IMAGE_DLLCHARACTERISTICS_TERMINAL_SERVER_AWARE 0x8000
+#define IMAGE_FIRST_SECTION(h) ((PIMAGE_SECTION_HEADER) ((ULONG_PTR)h+FIELD_OFFSET(IMAGE_NT_HEADERS,OptionalHeader)+((PIMAGE_NT_HEADERS)(h))->FileHeader.SizeOfOptionalHeader))
+#define IMAGE_DIRECTORY_ENTRY_EXPORT 0
+#define IMAGE_DIRECTORY_ENTRY_IMPORT 1
+#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2
+#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3
+#define IMAGE_DIRECTORY_ENTRY_SECURITY 4
+#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5
+#define IMAGE_DIRECTORY_ENTRY_DEBUG 6
+#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7
+#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8
+#define IMAGE_DIRECTORY_ENTRY_TLS 9
+#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10
+#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11
+#define IMAGE_DIRECTORY_ENTRY_IAT 12
+#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13
+#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14
+#define IMAGE_SCN_TYPE_REG 0
+#define IMAGE_SCN_TYPE_DSECT 1
+//#define IMAGE_SCN_TYPE_NOLOAD 2
+#define IMAGE_SCN_TYPE_GROUP 4
+#define IMAGE_SCN_TYPE_NO_PAD 8
+#define IMAGE_SCN_CNT_CODE 32
+#define IMAGE_SCN_CNT_INITIALIZED_DATA 64
+#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 128
+#define IMAGE_SCN_LNK_OTHER 256
+#define IMAGE_SCN_LNK_INFO 512
+#define IMAGE_SCN_LNK_REMOVE 2048
+#define IMAGE_SCN_LNK_COMDAT 4096
+#define IMAGE_SCN_MEM_FARDATA 0x8000
+#define IMAGE_SCN_MEM_PURGEABLE 0x20000
+#define IMAGE_SCN_MEM_16BIT 0x20000
+#define IMAGE_SCN_MEM_LOCKED 0x40000
+#define IMAGE_SCN_MEM_PRELOAD 0x80000
+#define IMAGE_SCN_ALIGN_1BYTES 0x100000
+#define IMAGE_SCN_ALIGN_2BYTES 0x200000
+#define IMAGE_SCN_ALIGN_4BYTES 0x300000
+#define IMAGE_SCN_ALIGN_8BYTES 0x400000
+#define IMAGE_SCN_ALIGN_16BYTES 0x500000
+#define IMAGE_SCN_ALIGN_32BYTES 0x600000
+#define IMAGE_SCN_ALIGN_64BYTES 0x700000
+#define IMAGE_SCN_LNK_NRELOC_OVFL 0x1000000
+#define IMAGE_SCN_MEM_DISCARDABLE 0x2000000
+#define IMAGE_SCN_MEM_NOT_CACHED 0x4000000
+#define IMAGE_SCN_MEM_NOT_PAGED 0x8000000
+#define IMAGE_SCN_MEM_SHARED 0x10000000
+#define IMAGE_SCN_MEM_EXECUTE 0x20000000
+#define IMAGE_SCN_MEM_READ 0x40000000
+#define IMAGE_SCN_MEM_WRITE 0x80000000
+#define IMAGE_SYM_UNDEFINED 0
+#define IMAGE_SYM_ABSOLUTE (-1)
+#define IMAGE_SYM_DEBUG (-2)
+#define IMAGE_SYM_TYPE_NULL 0
+#define IMAGE_SYM_TYPE_VOID 1
+#define IMAGE_SYM_TYPE_CHAR 2
+#define IMAGE_SYM_TYPE_SHORT 3
+#define IMAGE_SYM_TYPE_INT 4
+#define IMAGE_SYM_TYPE_LONG 5
+#define IMAGE_SYM_TYPE_FLOAT 6
+#define IMAGE_SYM_TYPE_DOUBLE 7
+#define IMAGE_SYM_TYPE_STRUCT 8
+#define IMAGE_SYM_TYPE_UNION 9
+#define IMAGE_SYM_TYPE_ENUM 10
+#define IMAGE_SYM_TYPE_MOE 11
+#define IMAGE_SYM_TYPE_BYTE 12
+#define IMAGE_SYM_TYPE_WORD 13
+#define IMAGE_SYM_TYPE_UINT 14
+#define IMAGE_SYM_TYPE_DWORD 15
+#define IMAGE_SYM_TYPE_PCODE 32768
+#define IMAGE_SYM_DTYPE_NULL 0
+#define IMAGE_SYM_DTYPE_POINTER 1
+#define IMAGE_SYM_DTYPE_FUNCTION 2
+#define IMAGE_SYM_DTYPE_ARRAY 3
+#define IMAGE_SYM_CLASS_END_OF_FUNCTION (-1)
+#define IMAGE_SYM_CLASS_NULL 0
+#define IMAGE_SYM_CLASS_AUTOMATIC 1
+#define IMAGE_SYM_CLASS_EXTERNAL 2
+#define IMAGE_SYM_CLASS_STATIC 3
+#define IMAGE_SYM_CLASS_REGISTER 4
+#define IMAGE_SYM_CLASS_EXTERNAL_DEF 5
+#define IMAGE_SYM_CLASS_LABEL 6
+#define IMAGE_SYM_CLASS_UNDEFINED_LABEL 7
+#define IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8
+#define IMAGE_SYM_CLASS_ARGUMENT 9
+#define IMAGE_SYM_CLASS_STRUCT_TAG 10
+#define IMAGE_SYM_CLASS_MEMBER_OF_UNION 11
+#define IMAGE_SYM_CLASS_UNION_TAG 12
+#define IMAGE_SYM_CLASS_TYPE_DEFINITION 13
+#define IMAGE_SYM_CLASS_UNDEFINED_STATIC 14
+#define IMAGE_SYM_CLASS_ENUM_TAG 15
+#define IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16
+#define IMAGE_SYM_CLASS_REGISTER_PARAM 17
+#define IMAGE_SYM_CLASS_BIT_FIELD 18
+#define IMAGE_SYM_CLASS_FAR_EXTERNAL 68
+#define IMAGE_SYM_CLASS_BLOCK 100
+#define IMAGE_SYM_CLASS_FUNCTION 101
+#define IMAGE_SYM_CLASS_END_OF_STRUCT 102
+#define IMAGE_SYM_CLASS_FILE 103
+#define IMAGE_SYM_CLASS_SECTION 104
+#define IMAGE_SYM_CLASS_WEAK_EXTERNAL 105
+#define IMAGE_COMDAT_SELECT_NODUPLICATES 1
+#define IMAGE_COMDAT_SELECT_ANY 2
+#define IMAGE_COMDAT_SELECT_SAME_SIZE 3
+#define IMAGE_COMDAT_SELECT_EXACT_MATCH 4
+#define IMAGE_COMDAT_SELECT_ASSOCIATIVE 5
+#define IMAGE_COMDAT_SELECT_LARGEST 6
+#define IMAGE_COMDAT_SELECT_NEWEST 7
+#define IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1
+#define IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2
+#define IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3
+#define IMAGE_REL_I386_ABSOLUTE 0
+#define IMAGE_REL_I386_DIR16 1
+#define IMAGE_REL_I386_REL16 2
+#define IMAGE_REL_I386_DIR32 6
+#define IMAGE_REL_I386_DIR32NB 7
+#define IMAGE_REL_I386_SEG12 9
+#define IMAGE_REL_I386_SECTION 10
+#define IMAGE_REL_I386_SECREL 11
+#define IMAGE_REL_I386_REL32 20
+#define IMAGE_REL_MIPS_ABSOLUTE 0
+#define IMAGE_REL_MIPS_REFHALF 1
+#define IMAGE_REL_MIPS_REFWORD 2
+#define IMAGE_REL_MIPS_JMPADDR 3
+#define IMAGE_REL_MIPS_REFHI 4
+#define IMAGE_REL_MIPS_REFLO 5
+#define IMAGE_REL_MIPS_GPREL 6
+#define IMAGE_REL_MIPS_LITERAL 7
+#define IMAGE_REL_MIPS_SECTION 10
+#define IMAGE_REL_MIPS_SECREL 11
+#define IMAGE_REL_MIPS_SECRELLO 12
+#define IMAGE_REL_MIPS_SECRELHI 13
+#define IMAGE_REL_MIPS_REFWORDNB 34
+#define IMAGE_REL_MIPS_PAIR 35
+#define IMAGE_REL_ALPHA_ABSOLUTE 0
+#define IMAGE_REL_ALPHA_REFLONG 1
+#define IMAGE_REL_ALPHA_REFQUAD 2
+#define IMAGE_REL_ALPHA_GPREL32 3
+#define IMAGE_REL_ALPHA_LITERAL 4
+#define IMAGE_REL_ALPHA_LITUSE 5
+#define IMAGE_REL_ALPHA_GPDISP 6
+#define IMAGE_REL_ALPHA_BRADDR 7
+#define IMAGE_REL_ALPHA_HINT 8
+#define IMAGE_REL_ALPHA_INLINE_REFLONG 9
+#define IMAGE_REL_ALPHA_REFHI 10
+#define IMAGE_REL_ALPHA_REFLO 11
+#define IMAGE_REL_ALPHA_PAIR 12
+#define IMAGE_REL_ALPHA_MATCH 13
+#define IMAGE_REL_ALPHA_SECTION 14
+#define IMAGE_REL_ALPHA_SECREL 15
+#define IMAGE_REL_ALPHA_REFLONGNB 16
+#define IMAGE_REL_ALPHA_SECRELLO 17
+#define IMAGE_REL_ALPHA_SECRELHI 18
+#define IMAGE_REL_PPC_ABSOLUTE 0
+#define IMAGE_REL_PPC_ADDR64 1
+#define IMAGE_REL_PPC_ADDR32 2
+#define IMAGE_REL_PPC_ADDR24 3
+#define IMAGE_REL_PPC_ADDR16 4
+#define IMAGE_REL_PPC_ADDR14 5
+#define IMAGE_REL_PPC_REL24 6
+#define IMAGE_REL_PPC_REL14 7
+#define IMAGE_REL_PPC_TOCREL16 8
+#define IMAGE_REL_PPC_TOCREL14 9
+#define IMAGE_REL_PPC_ADDR32NB 10
+#define IMAGE_REL_PPC_SECREL 11
+#define IMAGE_REL_PPC_SECTION 12
+#define IMAGE_REL_PPC_IFGLUE 13
+#define IMAGE_REL_PPC_IMGLUE 14
+#define IMAGE_REL_PPC_SECREL16 15
+#define IMAGE_REL_PPC_REFHI 16
+#define IMAGE_REL_PPC_REFLO 17
+#define IMAGE_REL_PPC_PAIR 18
+#define IMAGE_REL_PPC_TYPEMASK 255
+#define IMAGE_REL_PPC_NEG 256
+#define IMAGE_REL_PPC_BRTAKEN 512
+#define IMAGE_REL_PPC_BRNTAKEN 1024
+#define IMAGE_REL_PPC_TOCDEFN 2048
+#define IMAGE_REL_BASED_ABSOLUTE 0
+#define IMAGE_REL_BASED_HIGH 1
+#define IMAGE_REL_BASED_LOW 2
+#define IMAGE_REL_BASED_HIGHLOW 3
+#define IMAGE_REL_BASED_HIGHADJ 4
+#define IMAGE_REL_BASED_MIPS_JMPADDR 5
+#define IMAGE_REL_BASED_MIPS_JMPADDR16 9
+#define IMAGE_REL_BASED_IA64_IMM64 9
+#define IMAGE_REL_BASED_DIR64 10
+#define IMAGE_ARCHIVE_START_SIZE 8
+#define IMAGE_ARCHIVE_START "!<arch>\n"
+#define IMAGE_ARCHIVE_END "`\n"
+#define IMAGE_ARCHIVE_PAD "\n"
+#define IMAGE_ARCHIVE_LINKER_MEMBER "/ "
+#define IMAGE_ARCHIVE_LONGNAMES_MEMBER "// "
+#define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000
+#define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000
+#define IMAGE_DEBUG_TYPE_UNKNOWN 0
+#define IMAGE_DEBUG_TYPE_COFF 1
+#define IMAGE_DEBUG_TYPE_CODEVIEW 2
+#define IMAGE_DEBUG_TYPE_FPO 3
+#define IMAGE_DEBUG_TYPE_MISC 4
+#define IMAGE_DEBUG_TYPE_EXCEPTION 5
+#define IMAGE_DEBUG_TYPE_FIXUP 6
+#define IMAGE_DEBUG_TYPE_OMAP_TO_SRC 7
+#define IMAGE_DEBUG_TYPE_OMAP_FROM_SRC 8
+#define FRAME_FPO 0
+#define FRAME_TRAP 1
+#define FRAME_TSS 2
+#define FRAME_NONFPO 3
+#define IMAGE_DEBUG_MISC_EXENAME 1
+#define N_BTMASK 0x000F
+#define N_TMASK 0x0030
+#define N_TMASK1 0x00C0
+#define N_TMASK2 0x00F0
+#define N_BTSHFT 4
+#define N_TSHIFT 2
+#define IS_TEXT_UNICODE_ASCII16 1
+#define IS_TEXT_UNICODE_REVERSE_ASCII16 16
+#define IS_TEXT_UNICODE_STATISTICS 2
+#define IS_TEXT_UNICODE_REVERSE_STATISTICS 32
+#define IS_TEXT_UNICODE_CONTROLS 4
+#define IS_TEXT_UNICODE_REVERSE_CONTROLS 64
+#define IS_TEXT_UNICODE_SIGNATURE 8
+#define IS_TEXT_UNICODE_REVERSE_SIGNATURE 128
+#define IS_TEXT_UNICODE_ILLEGAL_CHARS 256
+#define IS_TEXT_UNICODE_ODD_LENGTH 512
+#define IS_TEXT_UNICODE_NULL_BYTES 4096
+#define IS_TEXT_UNICODE_UNICODE_MASK 15
+#define IS_TEXT_UNICODE_REVERSE_MASK 240
+#define IS_TEXT_UNICODE_NOT_UNICODE_MASK 3840
+#define IS_TEXT_UNICODE_NOT_ASCII_MASK 61440
+#define SERVICE_KERNEL_DRIVER 1
+#define SERVICE_FILE_SYSTEM_DRIVER 2
+#define SERVICE_ADAPTER 4
+#define SERVICE_RECOGNIZER_DRIVER 8
+#define SERVICE_DRIVER (SERVICE_KERNEL_DRIVER|SERVICE_FILE_SYSTEM_DRIVER|SERVICE_RECOGNIZER_DRIVER)
+#define SERVICE_WIN32_OWN_PROCESS 16
+#define SERVICE_WIN32_SHARE_PROCESS 32
+#define SERVICE_WIN32 (SERVICE_WIN32_OWN_PROCESS|SERVICE_WIN32_SHARE_PROCESS)
+#define SERVICE_INTERACTIVE_PROCESS 256
+#define SERVICE_TYPE_ALL (SERVICE_WIN32|SERVICE_ADAPTER|SERVICE_DRIVER|SERVICE_INTERACTIVE_PROCESS)
+#define SERVICE_BOOT_START 0
+#define SERVICE_SYSTEM_START 1
+#define SERVICE_AUTO_START 2
+#define SERVICE_DEMAND_START 3
+#define SERVICE_DISABLED 4
+#define SERVICE_ERROR_IGNORE 0
+#define SERVICE_ERROR_NORMAL 1
+#define SERVICE_ERROR_SEVERE 2
+#define SERVICE_ERROR_CRITICAL 3
+#define SE_OWNER_DEFAULTED 1
+#define SE_GROUP_DEFAULTED 2
+#define SE_DACL_PRESENT 4
+#define SE_DACL_DEFAULTED 8
+#define SE_SACL_PRESENT 16
+#define SE_SACL_DEFAULTED 32
+#define SE_DACL_AUTO_INHERIT_REQ 256
+#define SE_SACL_AUTO_INHERIT_REQ 512
+#define SE_DACL_AUTO_INHERITED 1024
+#define SE_SACL_AUTO_INHERITED 2048
+#define SE_DACL_PROTECTED 4096
+#define SE_SACL_PROTECTED 8192
+#define SE_RM_CONTROL_VALID 0x4000
+#define SE_SELF_RELATIVE 0x8000
+#define SECURITY_DESCRIPTOR_MIN_LENGTH 20
+#define SECURITY_DESCRIPTOR_REVISION 1
+#define SECURITY_DESCRIPTOR_REVISION1 1
+#define SE_PRIVILEGE_ENABLED_BY_DEFAULT 1
+#define SE_PRIVILEGE_ENABLED 2
+#define SE_PRIVILEGE_USED_FOR_ACCESS 0x80000000
+#define PRIVILEGE_SET_ALL_NECESSARY 1
+#define SECURITY_MAX_IMPERSONATION_LEVEL SecurityDelegation
+#define DEFAULT_IMPERSONATION_LEVEL SecurityImpersonation
+#define SECURITY_DYNAMIC_TRACKING TRUE
+#define SECURITY_STATIC_TRACKING FALSE
+/* also in ddk/ntifs.h */
+#define TOKEN_ASSIGN_PRIMARY (0x0001)
+#define TOKEN_DUPLICATE (0x0002)
+#define TOKEN_IMPERSONATE (0x0004)
+#define TOKEN_QUERY (0x0008)
+#define TOKEN_QUERY_SOURCE (0x0010)
+#define TOKEN_ADJUST_PRIVILEGES (0x0020)
+#define TOKEN_ADJUST_GROUPS (0x0040)
+#define TOKEN_ADJUST_DEFAULT (0x0080)
+#define TOKEN_ADJUST_SESSIONID (0x0100)
+#define TOKEN_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED |\
+ TOKEN_ASSIGN_PRIMARY |\
+ TOKEN_DUPLICATE |\
+ TOKEN_IMPERSONATE |\
+ TOKEN_QUERY |\
+ TOKEN_QUERY_SOURCE |\
+ TOKEN_ADJUST_PRIVILEGES |\
+ TOKEN_ADJUST_GROUPS |\
+ TOKEN_ADJUST_DEFAULT |\
+ TOKEN_ADJUST_SESSIONID)
+#define TOKEN_READ (STANDARD_RIGHTS_READ |\
+ TOKEN_QUERY)
+#define TOKEN_WRITE (STANDARD_RIGHTS_WRITE |\
+ TOKEN_ADJUST_PRIVILEGES |\
+ TOKEN_ADJUST_GROUPS |\
+ TOKEN_ADJUST_DEFAULT)
+
+#define TOKEN_EXECUTE (STANDARD_RIGHTS_EXECUTE)
+#define TOKEN_SOURCE_LENGTH 8
+/* end ddk/ntifs.h */
+#define DLL_PROCESS_DETACH 0
+#define DLL_PROCESS_ATTACH 1
+#define DLL_THREAD_ATTACH 2
+#define DLL_THREAD_DETACH 3
+#ifdef __WINESRC__
+#define DLL_WINE_PREATTACH 8 /* Never called, but defined for compatibility with Wine source */
+#endif
+#define TAPE_ABSOLUTE_POSITION 0
+#define TAPE_LOGICAL_POSITION 1
+#define TAPE_PSEUDO_LOGICAL_POSITION 2
+#define TAPE_REWIND 0
+#define TAPE_ABSOLUTE_BLOCK 1
+#define TAPE_LOGICAL_BLOCK 2
+#define TAPE_PSEUDO_LOGICAL_BLOCK 3
+#define TAPE_SPACE_END_OF_DATA 4
+#define TAPE_SPACE_RELATIVE_BLOCKS 5
+#define TAPE_SPACE_FILEMARKS 6
+#define TAPE_SPACE_SEQUENTIAL_FMKS 7
+#define TAPE_SPACE_SETMARKS 8
+#define TAPE_SPACE_SEQUENTIAL_SMKS 9
+#define TAPE_DRIVE_FIXED 1
+#define TAPE_DRIVE_SELECT 2
+#define TAPE_DRIVE_INITIATOR 4
+#define TAPE_DRIVE_ERASE_SHORT 16
+#define TAPE_DRIVE_ERASE_LONG 32
+#define TAPE_DRIVE_ERASE_BOP_ONLY 64
+#define TAPE_DRIVE_ERASE_IMMEDIATE 128
+#define TAPE_DRIVE_TAPE_CAPACITY 256
+#define TAPE_DRIVE_TAPE_REMAINING 512
+#define TAPE_DRIVE_FIXED_BLOCK 1024
+#define TAPE_DRIVE_VARIABLE_BLOCK 2048
+#define TAPE_DRIVE_WRITE_PROTECT 4096
+#define TAPE_DRIVE_EOT_WZ_SIZE 8192
+#define TAPE_DRIVE_ECC 0x10000
+#define TAPE_DRIVE_COMPRESSION 0x20000
+#define TAPE_DRIVE_PADDING 0x40000
+#define TAPE_DRIVE_REPORT_SMKS 0x80000
+#define TAPE_DRIVE_GET_ABSOLUTE_BLK 0x100000
+#define TAPE_DRIVE_GET_LOGICAL_BLK 0x200000
+#define TAPE_DRIVE_SET_EOT_WZ_SIZE 0x400000
+#define TAPE_DRIVE_EJECT_MEDIA 0x1000000
+#define TAPE_DRIVE_CLEAN_REQUESTS 0x2000000
+#define TAPE_DRIVE_SET_CMP_BOP_ONLY 0x4000000
+#define TAPE_DRIVE_RESERVED_BIT 0x80000000
+#define TAPE_DRIVE_LOAD_UNLOAD 0x80000001
+#define TAPE_DRIVE_TENSION 0x80000002
+#define TAPE_DRIVE_LOCK_UNLOCK 0x80000004
+#define TAPE_DRIVE_REWIND_IMMEDIATE 0x80000008
+#define TAPE_DRIVE_SET_BLOCK_SIZE 0x80000010
+#define TAPE_DRIVE_LOAD_UNLD_IMMED 0x80000020
+#define TAPE_DRIVE_TENSION_IMMED 0x80000040
+#define TAPE_DRIVE_LOCK_UNLK_IMMED 0x80000080
+#define TAPE_DRIVE_SET_ECC 0x80000100
+#define TAPE_DRIVE_SET_COMPRESSION 0x80000200
+#define TAPE_DRIVE_SET_PADDING 0x80000400
+#define TAPE_DRIVE_SET_REPORT_SMKS 0x80000800
+#define TAPE_DRIVE_ABSOLUTE_BLK 0x80001000
+#define TAPE_DRIVE_ABS_BLK_IMMED 0x80002000
+#define TAPE_DRIVE_LOGICAL_BLK 0x80004000
+#define TAPE_DRIVE_LOG_BLK_IMMED 0x80008000
+#define TAPE_DRIVE_END_OF_DATA 0x80010000
+#define TAPE_DRIVE_RELATIVE_BLKS 0x80020000
+#define TAPE_DRIVE_FILEMARKS 0x80040000
+#define TAPE_DRIVE_SEQUENTIAL_FMKS 0x80080000
+#define TAPE_DRIVE_SETMARKS 0x80100000
+#define TAPE_DRIVE_SEQUENTIAL_SMKS 0x80200000
+#define TAPE_DRIVE_REVERSE_POSITION 0x80400000
+#define TAPE_DRIVE_SPACE_IMMEDIATE 0x80800000
+#define TAPE_DRIVE_WRITE_SETMARKS 0x81000000
+#define TAPE_DRIVE_WRITE_FILEMARKS 0x82000000
+#define TAPE_DRIVE_WRITE_SHORT_FMKS 0x84000000
+#define TAPE_DRIVE_WRITE_LONG_FMKS 0x88000000
+#define TAPE_DRIVE_WRITE_MARK_IMMED 0x90000000
+#define TAPE_DRIVE_FORMAT 0xA0000000
+#define TAPE_DRIVE_FORMAT_IMMEDIATE 0xC0000000
+#define TAPE_DRIVE_HIGH_FEATURES 0x80000000
+#define TAPE_FIXED_PARTITIONS 0
+#define TAPE_INITIATOR_PARTITIONS 2
+#define TAPE_SELECT_PARTITIONS 1
+#define TAPE_FILEMARKS 1
+#define TAPE_LONG_FILEMARKS 3
+#define TAPE_SETMARKS 0
+#define TAPE_SHORT_FILEMARKS 2
+#define TAPE_ERASE_LONG 1
+#define TAPE_ERASE_SHORT 0
+#define TAPE_LOAD 0
+#define TAPE_UNLOAD 1
+#define TAPE_TENSION 2
+#define TAPE_LOCK 3
+#define TAPE_UNLOCK 4
+#define TAPE_FORMAT 5
+#if (_WIN32_WINNT >= 0x0500)
+#define VER_MINORVERSION 0x0000001
+#define VER_MAJORVERSION 0x0000002
+#define VER_BUILDNUMBER 0x0000004
+#define VER_PLATFORMID 0x0000008
+#define VER_SERVICEPACKMINOR 0x0000010
+#define VER_SERVICEPACKMAJOR 0x0000020
+#define VER_SUITENAME 0x0000040
+#define VER_PRODUCT_TYPE 0x0000080
+#define VER_EQUAL 1
+#define VER_GREATER 2
+#define VER_GREATER_EQUAL 3
+#define VER_LESS 4
+#define VER_LESS_EQUAL 5
+#define VER_AND 6
+#define VER_OR 7
+#endif
+#define VER_SERVER_NT 0x80000000
+#define VER_WORKSTATION_NT 0x40000000
+#define VER_PLATFORM_WIN32s 0
+#define VER_PLATFORM_WIN32_WINDOWS 1
+#define VER_PLATFORM_WIN32_NT 2
+#define VER_NT_WORKSTATION 1
+#define VER_NT_DOMAIN_CONTROLLER 2
+#define VER_NT_SERVER 3
+#define VER_SUITE_SMALLBUSINESS 1
+#define VER_SUITE_ENTERPRISE 2
+#define VER_SUITE_BACKOFFICE 4
+#define VER_SUITE_COMMUNICATIONS 8
+#define VER_SUITE_TERMINAL 16
+#define VER_SUITE_SMALLBUSINESS_RESTRICTED 32
+#define VER_SUITE_EMBEDDEDNT 64
+#define VER_SUITE_DATACENTER 128
+#define VER_SUITE_SINGLEUSERTS 256
+#define VER_SUITE_PERSONAL 512
+#define VER_SUITE_BLADE 1024
+#define VER_SUITE_EMBEDDED_RESTRICTED 2048
+#define VER_SUITE_SECURITY_APPLIANCE 4096
+#define VER_SUITE_STORAGE_SERVER 8192
+#define VER_SUITE_COMPUTE_SERVER 16384
+#define VER_SUITE_WH_SERVER 32768
+#define WT_EXECUTEDEFAULT 0x00000000
+#define WT_EXECUTEINIOTHREAD 0x00000001
+#define WT_EXECUTEINUITHREAD 0x00000002
+#define WT_EXECUTEINWAITTHREAD 0x00000004
+#define WT_EXECUTEONLYONCE 0x00000008
+#define WT_EXECUTELONGFUNCTION 0x00000010
+#define WT_EXECUTEINTIMERTHREAD 0x00000020
+#define WT_EXECUTEINPERSISTENTIOTHREAD 0x00000040
+#define WT_EXECUTEINPERSISTENTTHREAD 0x00000080
+#define WT_TRANSFER_IMPERSONATION 0x00000100
+#define WT_SET_MAX_THREADPOOL_THREADS(flags,limit) ((flags)|=(limit)<<16)
+typedef VOID (NTAPI *WORKERCALLBACKFUNC)(PVOID);
+#if (_WIN32_WINNT >= 0x0501)
+#define ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION 1
+#define ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION 2
+#define ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION 3
+#define ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION 4
+#define ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION 5
+#define ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION 6
+#define ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION 7
+#define ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES 9
+#endif /* (_WIN32_WINNT >= 0x0501) */
+#define BTYPE(x) ((x)&N_BTMASK)
+#define ISPTR(x) (((x)&N_TMASK)==(IMAGE_SYM_DTYPE_POINTER<<N_BTSHFT))
+#define ISFCN(x) (((x)&N_TMASK)==(IMAGE_SYM_DTYPE_FUNCTION<<N_BTSHFT))
+#define ISARY(x) (((x)&N_TMASK)==(IMAGE_SYM_DTYPE_ARRAY<<N_BTSHFT))
+#define ISTAG(x) ((x)==IMAGE_SYM_CLASS_STRUCT_TAG||(x)==IMAGE_SYM_CLASS_UNION_TAG||(x)==IMAGE_SYM_CLASS_ENUM_TAG)
+#define INCREF(x) ((((x)&~N_BTMASK)<<N_TSHIFT)|(IMAGE_SYM_DTYPE_POINTER<<N_BTSHFT)|((x)&N_BTMASK))
+#define DECREF(x) ((((x)>>N_TSHIFT)&~N_BTMASK)|((x)&N_BTMASK))
+#define TLS_MINIMUM_AVAILABLE 64
+#define FLS_MAXIMUM_AVAILABLE 128
+#define REPARSE_GUID_DATA_BUFFER_HEADER_SIZE FIELD_OFFSET(REPARSE_GUID_DATA_BUFFER, GenericReparseBuffer)
+#define MAXIMUM_REPARSE_DATA_BUFFER_SIZE 16384
+#define IO_REPARSE_TAG_RESERVED_ZERO 0
+#define IO_REPARSE_TAG_RESERVED_ONE 1
+#define IO_REPARSE_TAG_RESERVED_RANGE IO_REPARSE_TAG_RESERVED_ONE
+#define IsReparseTagMicrosoft(x) ((x)&0x80000000)
+#define IsReparseTagHighLatency(x) ((x)&0x40000000)
+#define IsReparseTagNameSurrogate(x) ((x)&0x20000000)
+#define IO_REPARSE_TAG_VALID_VALUES 0xE000FFFF
+#define IsReparseTagValid(x) (!((x)&~IO_REPARSE_TAG_VALID_VALUES)&&((x)>IO_REPARSE_TAG_RESERVED_RANGE))
+#define IO_REPARSE_TAG_SYMBOLIC_LINK IO_REPARSE_TAG_RESERVED_ZERO
+#define IO_REPARSE_TAG_MOUNT_POINT 0xA0000003
+#define IO_REPARSE_TAG_SYMLINK 0xA000000CL
+#ifndef RC_INVOKED
+typedef DWORD ACCESS_MASK, *PACCESS_MASK;
+
+#ifdef _GUID_DEFINED
+# warning _GUID_DEFINED is deprecated, use GUID_DEFINED instead
+#endif
+
+#if ! (defined _GUID_DEFINED || defined GUID_DEFINED) /* also defined in basetyps.h */
+#define GUID_DEFINED
+typedef struct _GUID {
+ unsigned long Data1;
+ unsigned short Data2;
+ unsigned short Data3;
+ unsigned char Data4[8];
+} GUID, *REFGUID, *LPGUID;
+#endif /* GUID_DEFINED */
+
+#define SYSTEM_LUID { 0x3E7, 0x0 }
+
+/* ACE Access Types, also in ntifs.h */
+#define ACCESS_MIN_MS_ACE_TYPE (0x0)
+#define ACCESS_ALLOWED_ACE_TYPE (0x0)
+#define ACCESS_DENIED_ACE_TYPE (0x1)
+#define SYSTEM_AUDIT_ACE_TYPE (0x2)
+#define SYSTEM_ALARM_ACE_TYPE (0x3)
+#define ACCESS_MAX_MS_V2_ACE_TYPE (0x3)
+#define ACCESS_ALLOWED_COMPOUND_ACE_TYPE (0x4)
+#define ACCESS_MAX_MS_V3_ACE_TYPE (0x4)
+#define ACCESS_MIN_MS_OBJECT_ACE_TYPE (0x5)
+#define ACCESS_ALLOWED_OBJECT_ACE_TYPE (0x5)
+#define ACCESS_DENIED_OBJECT_ACE_TYPE (0x6)
+#define SYSTEM_AUDIT_OBJECT_ACE_TYPE (0x7)
+#define SYSTEM_ALARM_OBJECT_ACE_TYPE (0x8)
+#define ACCESS_MAX_MS_OBJECT_ACE_TYPE (0x8)
+#define ACCESS_MAX_MS_V4_ACE_TYPE (0x8)
+#define ACCESS_MAX_MS_ACE_TYPE (0x8)
+#define ACCESS_ALLOWED_CALLBACK_ACE_TYPE (0x9)
+#define ACCESS_DENIED_CALLBACK_ACE_TYPE (0xA)
+#define ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE (0xB)
+#define ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE (0xC)
+#define SYSTEM_AUDIT_CALLBACK_ACE_TYPE (0xD)
+#define SYSTEM_ALARM_CALLBACK_ACE_TYPE (0xE)
+#define SYSTEM_AUDIT_CALLBACK_OBJECT_ACE_TYPE (0xF)
+#define SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE (0x10)
+#define SYSTEM_MANDATORY_LABEL_ACE_TYPE (0x11)
+#define ACCESS_MAX_MS_V5_ACE_TYPE (0x11)
+/* end ntifs.h */
+
+typedef struct _GENERIC_MAPPING {
+ ACCESS_MASK GenericRead;
+ ACCESS_MASK GenericWrite;
+ ACCESS_MASK GenericExecute;
+ ACCESS_MASK GenericAll;
+} GENERIC_MAPPING, *PGENERIC_MAPPING;
+
+typedef struct _ACE_HEADER {
+ BYTE AceType;
+ BYTE AceFlags;
+ WORD AceSize;
+} ACE_HEADER, *PACE_HEADER;
+
+typedef struct _ACCESS_ALLOWED_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD SidStart;
+} ACCESS_ALLOWED_ACE, *PACCESS_ALLOWED_ACE;
+
+typedef struct _ACCESS_DENIED_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD SidStart;
+} ACCESS_DENIED_ACE, *PACCESS_DENIED_ACE;
+
+typedef struct _SYSTEM_AUDIT_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD SidStart;
+} SYSTEM_AUDIT_ACE, *PSYSTEM_AUDIT_ACE;
+
+typedef struct _SYSTEM_ALARM_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD SidStart;
+} SYSTEM_ALARM_ACE,*PSYSTEM_ALARM_ACE;
+
+typedef struct _SYSTEM_MANDATORY_LABEL_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD SidStart;
+} SYSTEM_MANDATORY_LABEL_ACE, *PSYSTEM_MANDATORY_LABEL_ACE;
+
+#define SYSTEM_MANDATORY_LABEL_NO_WRITE_UP 0x1
+#define SYSTEM_MANDATORY_LABEL_NO_READ_UP 0x2
+#define SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP 0x4
+#define SYSTEM_MANDATORY_LABEL_VALID_MASK (SYSTEM_MANDATORY_LABEL_NO_WRITE_UP | SYSTEM_MANDATORY_LABEL_NO_READ_UP | SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP)
+
+typedef struct _ACCESS_ALLOWED_OBJECT_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD Flags;
+ GUID ObjectType;
+ GUID InheritedObjectType;
+ DWORD SidStart;
+} ACCESS_ALLOWED_OBJECT_ACE,*PACCESS_ALLOWED_OBJECT_ACE;
+
+typedef struct _ACCESS_DENIED_OBJECT_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD Flags;
+ GUID ObjectType;
+ GUID InheritedObjectType;
+ DWORD SidStart;
+} ACCESS_DENIED_OBJECT_ACE,*PACCESS_DENIED_OBJECT_ACE;
+
+typedef struct _SYSTEM_AUDIT_OBJECT_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD Flags;
+ GUID ObjectType;
+ GUID InheritedObjectType;
+ DWORD SidStart;
+} SYSTEM_AUDIT_OBJECT_ACE,*PSYSTEM_AUDIT_OBJECT_ACE;
+
+typedef struct _SYSTEM_ALARM_OBJECT_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD Flags;
+ GUID ObjectType;
+ GUID InheritedObjectType;
+ DWORD SidStart;
+} SYSTEM_ALARM_OBJECT_ACE,*PSYSTEM_ALARM_OBJECT_ACE;
+
+typedef struct _ACCESS_ALLOWED_CALLBACK_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD SidStart;
+} ACCESS_ALLOWED_CALLBACK_ACE, *PACCESS_ALLOWED_CALLBACK_ACE;
+
+typedef struct _ACCESS_DENIED_CALLBACK_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD SidStart;
+} ACCESS_DENIED_CALLBACK_ACE, *PACCESS_DENIED_CALLBACK_ACE;
+
+typedef struct _SYSTEM_AUDIT_CALLBACK_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD SidStart;
+} SYSTEM_AUDIT_CALLBACK_ACE, *PSYSTEM_AUDIT_CALLBACK_ACE;
+
+typedef struct _SYSTEM_ALARM_CALLBACK_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD SidStart;
+} SYSTEM_ALARM_CALLBACK_ACE, *PSYSTEM_ALARM_CALLBACK_ACE;
+
+typedef struct _ACCESS_ALLOWED_CALLBACK_OBJECT_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD Flags;
+ GUID ObjectType;
+ GUID InheritedObjectType;
+ DWORD SidStart;
+} ACCESS_ALLOWED_CALLBACK_OBJECT_ACE, *PACCESS_ALLOWED_CALLBACK_OBJECT_ACE;
+
+typedef struct _ACCESS_DENIED_CALLBACK_OBJECT_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD Flags;
+ GUID ObjectType;
+ GUID InheritedObjectType;
+ DWORD SidStart;
+} ACCESS_DENIED_CALLBACK_OBJECT_ACE, *PACCESS_DENIED_CALLBACK_OBJECT_ACE;
+
+typedef struct _SYSTEM_AUDIT_CALLBACK_OBJECT_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD Flags;
+ GUID ObjectType;
+ GUID InheritedObjectType;
+ DWORD SidStart;
+} SYSTEM_AUDIT_CALLBACK_OBJECT_ACE, *PSYSTEM_AUDIT_CALLBACK_OBJECT_ACE;
+
+typedef struct _SYSTEM_ALARM_CALLBACK_OBJECT_ACE {
+ ACE_HEADER Header;
+ ACCESS_MASK Mask;
+ DWORD Flags;
+ GUID ObjectType;
+ GUID InheritedObjectType;
+ DWORD SidStart;
+} SYSTEM_ALARM_CALLBACK_OBJECT_ACE, *PSYSTEM_ALARM_CALLBACK_OBJECT_ACE;
+
+typedef struct _ACL {
+ BYTE AclRevision;
+ BYTE Sbz1;
+ WORD AclSize;
+ WORD AceCount;
+ WORD Sbz2;
+} ACL,*PACL;
+
+typedef enum _ACL_INFORMATION_CLASS {
+ AclRevisionInformation = 1,
+ AclSizeInformation
+} ACL_INFORMATION_CLASS;
+
+typedef struct _ACL_REVISION_INFORMATION {
+ DWORD AclRevision;
+} ACL_REVISION_INFORMATION, *PACL_REVISION_INFORMATION;
+
+typedef struct _ACL_SIZE_INFORMATION {
+ DWORD AceCount;
+ DWORD AclBytesInUse;
+ DWORD AclBytesFree;
+} ACL_SIZE_INFORMATION, *PACL_SIZE_INFORMATION;
+
+#ifndef _LDT_ENTRY_DEFINED
+#define _LDT_ENTRY_DEFINED
+
+typedef struct _LDT_ENTRY {
+ WORD LimitLow;
+ WORD BaseLow;
+ union {
+ struct {
+ BYTE BaseMid;
+ BYTE Flags1;
+ BYTE Flags2;
+ BYTE BaseHi;
+ } Bytes;
+ struct {
+ DWORD BaseMid:8;
+ DWORD Type:5;
+ DWORD Dpl:2;
+ DWORD Pres:1;
+ DWORD LimitHi:4;
+ DWORD Sys:1;
+ DWORD Reserved_0:1;
+ DWORD Default_Big:1;
+ DWORD Granularity:1;
+ DWORD BaseHi:8;
+ } Bits;
+ } HighWord;
+} LDT_ENTRY, *PLDT_ENTRY, *LPLDT_ENTRY;
+
+#endif /* _LDT_ENTRY_DEFINED */
+
+/* FIXME: add more machines */
+#if defined(_X86_) && !defined(__PowerPC__)
+#define SIZE_OF_80387_REGISTERS 80
+#define CONTEXT_i386 0x10000
+#define CONTEXT_i486 0x10000
+#define CONTEXT_CONTROL (CONTEXT_i386|0x00000001L)
+#define CONTEXT_INTEGER (CONTEXT_i386|0x00000002L)
+#define CONTEXT_SEGMENTS (CONTEXT_i386|0x00000004L)
+#define CONTEXT_FLOATING_POINT (CONTEXT_i386|0x00000008L)
+#define CONTEXT_DEBUG_REGISTERS (CONTEXT_i386|0x00000010L)
+#define CONTEXT_EXTENDED_REGISTERS (CONTEXT_i386|0x00000020L)
+#define CONTEXT_FULL (CONTEXT_CONTROL|CONTEXT_INTEGER|CONTEXT_SEGMENTS)
+#define MAXIMUM_SUPPORTED_EXTENSION 512
+
+#define EXCEPTION_READ_FAULT 0
+#define EXCEPTION_WRITE_FAULT 1
+#define EXCEPTION_EXECUTE_FAULT 8
+
+typedef struct _FLOATING_SAVE_AREA {
+ DWORD ControlWord;
+ DWORD StatusWord;
+ DWORD TagWord;
+ DWORD ErrorOffset;
+ DWORD ErrorSelector;
+ DWORD DataOffset;
+ DWORD DataSelector;
+ BYTE RegisterArea[80];
+ DWORD Cr0NpxState;
+} FLOATING_SAVE_AREA, *PFLOATING_SAVE_AREA;
+
+typedef struct _CONTEXT {
+ DWORD ContextFlags;
+ DWORD Dr0;
+ DWORD Dr1;
+ DWORD Dr2;
+ DWORD Dr3;
+ DWORD Dr6;
+ DWORD Dr7;
+ FLOATING_SAVE_AREA FloatSave;
+ DWORD SegGs;
+ DWORD SegFs;
+ DWORD SegEs;
+ DWORD SegDs;
+ DWORD Edi;
+ DWORD Esi;
+ DWORD Ebx;
+ DWORD Edx;
+ DWORD Ecx;
+ DWORD Eax;
+ DWORD Ebp;
+ DWORD Eip;
+ DWORD SegCs;
+ DWORD EFlags;
+ DWORD Esp;
+ DWORD SegSs;
+ BYTE ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];
+} CONTEXT;
+#elif defined(__x86_64__)
+
+#define CONTEXT_AMD64 0x100000
+
+#if !defined(RC_INVOKED)
+#define CONTEXT_CONTROL (CONTEXT_AMD64 | 0x1L)
+#define CONTEXT_INTEGER (CONTEXT_AMD64 | 0x2L)
+#define CONTEXT_SEGMENTS (CONTEXT_AMD64 | 0x4L)
+#define CONTEXT_FLOATING_POINT (CONTEXT_AMD64 | 0x8L)
+#define CONTEXT_DEBUG_REGISTERS (CONTEXT_AMD64 | 0x10L)
+
+#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT)
+#define CONTEXT_ALL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS)
+
+#define CONTEXT_EXCEPTION_ACTIVE 0x8000000
+#define CONTEXT_SERVICE_ACTIVE 0x10000000
+#define CONTEXT_EXCEPTION_REQUEST 0x40000000
+#define CONTEXT_EXCEPTION_REPORTING 0x80000000
+#endif
+
+#define INITIAL_MXCSR 0x1f80
+#define INITIAL_FPCSR 0x027f
+#define EXCEPTION_READ_FAULT 0
+#define EXCEPTION_WRITE_FAULT 1
+#define EXCEPTION_EXECUTE_FAULT 8
+
+typedef struct DECLSPEC_ALIGN(16) _M128A {
+ ULONGLONG Low;
+ LONGLONG High;
+} M128A, *PM128A;
+
+typedef struct _XMM_SAVE_AREA32 {
+ WORD ControlWord;
+ WORD StatusWord;
+ BYTE TagWord;
+ BYTE Reserved1;
+ WORD ErrorOpcode;
+ DWORD ErrorOffset;
+ WORD ErrorSelector;
+ WORD Reserved2;
+ DWORD DataOffset;
+ WORD DataSelector;
+ WORD Reserved3;
+ DWORD MxCsr;
+ DWORD MxCsr_Mask;
+ M128A FloatRegisters[8];
+ M128A XmmRegisters[16];
+ BYTE Reserved4[96];
+} XMM_SAVE_AREA32, *PXMM_SAVE_AREA32;
+
+typedef struct DECLSPEC_ALIGN(16) _CONTEXT {
+ DWORD64 P1Home;
+ DWORD64 P2Home;
+ DWORD64 P3Home;
+ DWORD64 P4Home;
+ DWORD64 P5Home;
+ DWORD64 P6Home;
+
+ /* Control flags */
+ DWORD ContextFlags;
+ DWORD MxCsr;
+
+ /* Segment */
+ WORD SegCs;
+ WORD SegDs;
+ WORD SegEs;
+ WORD SegFs;
+ WORD SegGs;
+ WORD SegSs;
+ DWORD EFlags;
+
+ /* Debug */
+ DWORD64 Dr0;
+ DWORD64 Dr1;
+ DWORD64 Dr2;
+ DWORD64 Dr3;
+ DWORD64 Dr6;
+ DWORD64 Dr7;
+
+ /* Integer */
+ DWORD64 Rax;
+ DWORD64 Rcx;
+ DWORD64 Rdx;
+ DWORD64 Rbx;
+ DWORD64 Rsp;
+ DWORD64 Rbp;
+ DWORD64 Rsi;
+ DWORD64 Rdi;
+ DWORD64 R8;
+ DWORD64 R9;
+ DWORD64 R10;
+ DWORD64 R11;
+ DWORD64 R12;
+ DWORD64 R13;
+ DWORD64 R14;
+ DWORD64 R15;
+
+ /* Counter */
+ DWORD64 Rip;
+
+ /* Floating point */
+ union {
+ XMM_SAVE_AREA32 FltSave;
+ struct {
+ M128A Header[2];
+ M128A Legacy[8];
+ M128A Xmm0;
+ M128A Xmm1;
+ M128A Xmm2;
+ M128A Xmm3;
+ M128A Xmm4;
+ M128A Xmm5;
+ M128A Xmm6;
+ M128A Xmm7;
+ M128A Xmm8;
+ M128A Xmm9;
+ M128A Xmm10;
+ M128A Xmm11;
+ M128A Xmm12;
+ M128A Xmm13;
+ M128A Xmm14;
+ M128A Xmm15;
+ } DUMMYSTRUCTNAME;
+ } DUMMYUNIONNAME;
+
+ /* Vector */
+ M128A VectorRegister[26];
+ DWORD64 VectorControl;
+
+ /* Debug control */
+ DWORD64 DebugControl;
+ DWORD64 LastBranchToRip;
+ DWORD64 LastBranchFromRip;
+ DWORD64 LastExceptionToRip;
+ DWORD64 LastExceptionFromRip;
+} CONTEXT;
+
+
+typedef struct _KNONVOLATILE_CONTEXT_POINTERS {
+ union {
+ PM128A FloatingContext[16];
+ struct {
+ PM128A Xmm0;
+ PM128A Xmm1;
+ PM128A Xmm2;
+ PM128A Xmm3;
+ PM128A Xmm4;
+ PM128A Xmm5;
+ PM128A Xmm6;
+ PM128A Xmm7;
+ PM128A Xmm8;
+ PM128A Xmm9;
+ PM128A Xmm10;
+ PM128A Xmm11;
+ PM128A Xmm12;
+ PM128A Xmm13;
+ PM128A Xmm14;
+ PM128A Xmm15;
+ } DUMMYSTRUCTNAME;
+ } DUMMYUNIONNAME;
+
+ union {
+ PULONG64 IntegerContext[16];
+ struct {
+ PULONG64 Rax;
+ PULONG64 Rcx;
+ PULONG64 Rdx;
+ PULONG64 Rbx;
+ PULONG64 Rsp;
+ PULONG64 Rbp;
+ PULONG64 Rsi;
+ PULONG64 Rdi;
+ PULONG64 R8;
+ PULONG64 R9;
+ PULONG64 R10;
+ PULONG64 R11;
+ PULONG64 R12;
+ PULONG64 R13;
+ PULONG64 R14;
+ PULONG64 R15;
+ } DUMMYSTRUCTNAME;
+ } DUMMYUNIONNAME2;
+} KNONVOLATILE_CONTEXT_POINTERS, *PKNONVOLATILE_CONTEXT_POINTERS;
+
+#define RUNTIME_FUNCTION_INDIRECT 0x1
+
+typedef struct _RUNTIME_FUNCTION {
+ DWORD BeginAddress;
+ DWORD EndAddress;
+ DWORD UnwindData;
+} RUNTIME_FUNCTION,*PRUNTIME_FUNCTION;
+
+#define UNWIND_HISTORY_TABLE_SIZE 12
+
+typedef struct _UNWIND_HISTORY_TABLE_ENTRY
+{
+ ULONG64 ImageBase;
+ PRUNTIME_FUNCTION FunctionEntry;
+} UNWIND_HISTORY_TABLE_ENTRY, *PUNWIND_HISTORY_TABLE_ENTRY;
+
+typedef struct _UNWIND_HISTORY_TABLE
+{
+ ULONG Count;
+ UCHAR Search;
+ ULONG64 LowAddress;
+ ULONG64 HighAddress;
+ UNWIND_HISTORY_TABLE_ENTRY Entry[UNWIND_HISTORY_TABLE_SIZE];
+} UNWIND_HISTORY_TABLE, *PUNWIND_HISTORY_TABLE;
+
+typedef PRUNTIME_FUNCTION (*PGET_RUNTIME_FUNCTION_CALLBACK)(DWORD64 ControlPc,PVOID Context);
+typedef DWORD (*POUT_OF_PROCESS_FUNCTION_TABLE_CALLBACK)(HANDLE Process,PVOID TableAddress,PDWORD Entries,PRUNTIME_FUNCTION *Functions);
+
+#define OUT_OF_PROCESS_FUNCTION_TABLE_CALLBACK_EXPORT_NAME "OutOfProcessFunctionTableCallback"
+
+NTSYSAPI
+VOID
+__cdecl
+RtlRestoreContext(struct _CONTEXT *ContextRecord,
+ struct _EXCEPTION_RECORD *ExceptionRecord);
+
+NTSYSAPI
+BOOLEAN
+__cdecl
+RtlAddFunctionTable(PRUNTIME_FUNCTION FunctionTable,
+ DWORD EntryCount,
+ DWORD64 BaseAddress);
+
+NTSYSAPI
+BOOLEAN
+__cdecl
+RtlInstallFunctionTableCallback(DWORD64 TableIdentifier,
+ DWORD64 BaseAddress,
+ DWORD Length,
+ PGET_RUNTIME_FUNCTION_CALLBACK Callback,
+ PVOID Context,
+ PCWSTR OutOfProcessCallbackDll);
+
+NTSYSAPI
+BOOLEAN
+__cdecl
+RtlDeleteFunctionTable(PRUNTIME_FUNCTION FunctionTable);
+
+#elif defined(_PPC_)
+#define CONTEXT_CONTROL 1L
+#define CONTEXT_FLOATING_POINT 2L
+#define CONTEXT_INTEGER 4L
+#define CONTEXT_DEBUG_REGISTERS 8L
+#define CONTEXT_FULL (CONTEXT_CONTROL|CONTEXT_FLOATING_POINT|CONTEXT_INTEGER)
+typedef struct _FLOATING_SAVE_AREA
+{
+ double Fpr0;
+ double Fpr1;
+ double Fpr2;
+ double Fpr3;
+ double Fpr4;
+ double Fpr5;
+ double Fpr6;
+ double Fpr7;
+ double Fpr8;
+ double Fpr9;
+ double Fpr10;
+ double Fpr11;
+ double Fpr12;
+ double Fpr13;
+ double Fpr14;
+ double Fpr15;
+ double Fpr16;
+ double Fpr17;
+ double Fpr18;
+ double Fpr19;
+ double Fpr20;
+ double Fpr21;
+ double Fpr22;
+ double Fpr23;
+ double Fpr24;
+ double Fpr25;
+ double Fpr26;
+ double Fpr27;
+ double Fpr28;
+ double Fpr29;
+ double Fpr30;
+ double Fpr31;
+ double Fpscr;
+} FLOATING_SAVE_AREA;
+
+typedef struct _CONTEXT {
+ FLOATING_SAVE_AREA FloatSave;
+ DWORD Gpr0;
+ DWORD Gpr1;
+ DWORD Gpr2;
+ DWORD Gpr3;
+ DWORD Gpr4;
+ DWORD Gpr5;
+ DWORD Gpr6;
+ DWORD Gpr7;
+ DWORD Gpr8;
+ DWORD Gpr9;
+ DWORD Gpr10;
+ DWORD Gpr11;
+ DWORD Gpr12;
+ DWORD Gpr13;
+ DWORD Gpr14;
+ DWORD Gpr15;
+ DWORD Gpr16;
+ DWORD Gpr17;
+ DWORD Gpr18;
+ DWORD Gpr19;
+ DWORD Gpr20;
+ DWORD Gpr21;
+ DWORD Gpr22;
+ DWORD Gpr23;
+ DWORD Gpr24;
+ DWORD Gpr25;
+ DWORD Gpr26;
+ DWORD Gpr27;
+ DWORD Gpr28;
+ DWORD Gpr29;
+ DWORD Gpr30;
+ DWORD Gpr31;
+ DWORD Cr;
+ DWORD Xer;
+ DWORD Msr;
+ DWORD Iar;
+ DWORD Lr;
+ DWORD Ctr;
+ DWORD ContextFlags;
+ DWORD Fill[3];
+ DWORD Dr0;
+ DWORD Dr1;
+ DWORD Dr2;
+ DWORD Dr3;
+ DWORD Dr4;
+ DWORD Dr5;
+ DWORD Dr6;
+ DWORD Dr7;
+} CONTEXT;
+#elif defined(_ALPHA_)
+#define CONTEXT_ALPHA 0x20000
+#define CONTEXT_CONTROL (CONTEXT_ALPHA|1L)
+#define CONTEXT_FLOATING_POINT (CONTEXT_ALPHA|2L)
+#define CONTEXT_INTEGER (CONTEXT_ALPHA|4L)
+#define CONTEXT_FULL (CONTEXT_CONTROL|CONTEXT_FLOATING_POINT|CONTEXT_INTEGER)
+typedef struct _CONTEXT {
+ ULONGLONG FltF0;
+ ULONGLONG FltF1;
+ ULONGLONG FltF2;
+ ULONGLONG FltF3;
+ ULONGLONG FltF4;
+ ULONGLONG FltF5;
+ ULONGLONG FltF6;
+ ULONGLONG FltF7;
+ ULONGLONG FltF8;
+ ULONGLONG FltF9;
+ ULONGLONG FltF10;
+ ULONGLONG FltF11;
+ ULONGLONG FltF12;
+ ULONGLONG FltF13;
+ ULONGLONG FltF14;
+ ULONGLONG FltF15;
+ ULONGLONG FltF16;
+ ULONGLONG FltF17;
+ ULONGLONG FltF18;
+ ULONGLONG FltF19;
+ ULONGLONG FltF20;
+ ULONGLONG FltF21;
+ ULONGLONG FltF22;
+ ULONGLONG FltF23;
+ ULONGLONG FltF24;
+ ULONGLONG FltF25;
+ ULONGLONG FltF26;
+ ULONGLONG FltF27;
+ ULONGLONG FltF28;
+ ULONGLONG FltF29;
+ ULONGLONG FltF30;
+ ULONGLONG FltF31;
+ ULONGLONG IntV0;
+ ULONGLONG IntT0;
+ ULONGLONG IntT1;
+ ULONGLONG IntT2;
+ ULONGLONG IntT3;
+ ULONGLONG IntT4;
+ ULONGLONG IntT5;
+ ULONGLONG IntT6;
+ ULONGLONG IntT7;
+ ULONGLONG IntS0;
+ ULONGLONG IntS1;
+ ULONGLONG IntS2;
+ ULONGLONG IntS3;
+ ULONGLONG IntS4;
+ ULONGLONG IntS5;
+ ULONGLONG IntFp;
+ ULONGLONG IntA0;
+ ULONGLONG IntA1;
+ ULONGLONG IntA2;
+ ULONGLONG IntA3;
+ ULONGLONG IntA4;
+ ULONGLONG IntA5;
+ ULONGLONG IntT8;
+ ULONGLONG IntT9;
+ ULONGLONG IntT10;
+ ULONGLONG IntT11;
+ ULONGLONG IntRa;
+ ULONGLONG IntT12;
+ ULONGLONG IntAt;
+ ULONGLONG IntGp;
+ ULONGLONG IntSp;
+ ULONGLONG IntZero;
+ ULONGLONG Fpcr;
+ ULONGLONG SoftFpcr;
+ ULONGLONG Fir;
+ DWORD Psr;
+ DWORD ContextFlags;
+ DWORD Fill[4];
+} CONTEXT;
+#elif defined(SHx)
+
+/* These are the debug or break registers on the SH3 */
+typedef struct _DEBUG_REGISTERS {
+ ULONG BarA;
+ UCHAR BasrA;
+ UCHAR BamrA;
+ USHORT BbrA;
+ ULONG BarB;
+ UCHAR BasrB;
+ UCHAR BamrB;
+ USHORT BbrB;
+ ULONG BdrB;
+ ULONG BdmrB;
+ USHORT Brcr;
+ USHORT Align;
+} DEBUG_REGISTERS, *PDEBUG_REGISTERS;
+
+/* The following flags control the contents of the CONTEXT structure. */
+
+#define CONTEXT_SH3 0x00000040
+#define CONTEXT_SH4 0x000000c0 /* CONTEXT_SH3 | 0x80 - must contain the SH3 bits */
+
+#ifdef SH3
+#define CONTEXT_CONTROL (CONTEXT_SH3 | 0x00000001L)
+#define CONTEXT_INTEGER (CONTEXT_SH3 | 0x00000002L)
+#define CONTEXT_DEBUG_REGISTERS (CONTEXT_SH3 | 0x00000008L)
+#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_DEBUG_REGISTERS)
+#else /* SH4 */
+#define CONTEXT_CONTROL (CONTEXT_SH4 | 0x00000001L)
+#define CONTEXT_INTEGER (CONTEXT_SH4 | 0x00000002L)
+#define CONTEXT_DEBUG_REGISTERS (CONTEXT_SH4 | 0x00000008L)
+#define CONTEXT_FLOATING_POINT (CONTEXT_SH4 | 0x00000004L)
+#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_DEBUG_REGISTERS | CONTEXT_FLOATING_POINT)
+#endif
+
+/* Context Frame */
+
+/* This frame is used to store a limited processor context into the */
+/* Thread structure for CPUs which have no floating point support. */
+
+typedef struct _CONTEXT {
+ /* The flags values within this flag control the contents of */
+ /* a CONTEXT record. */
+
+ /* If the context record is used as an input parameter, then */
+ /* for each portion of the context record controlled by a flag */
+ /* whose value is set, it is assumed that that portion of the */
+ /* context record contains valid context. If the context record */
+ /* is being used to modify a thread's context, then only that */
+ /* portion of the threads context will be modified. */
+
+ /* If the context record is used as an IN OUT parameter to capture */
+ /* the context of a thread, then only those portions of the thread's */
+ /* context corresponding to set flags will be returned. */
+
+ /* The context record is never used as an OUT only parameter. */
+
+
+ ULONG ContextFlags;
+
+ /* This section is specified/returned if the ContextFlags word contains */
+ /* the flag CONTEXT_INTEGER. */
+
+ /* N.B. The registers RA and R15 are defined in this section, but are */
+ /* considered part of the control context rather than part of the integer */
+ /* context. */
+
+ ULONG PR;
+ ULONG MACH;
+ ULONG MACL;
+ ULONG GBR;
+ ULONG R0;
+ ULONG R1;
+ ULONG R2;
+ ULONG R3;
+ ULONG R4;
+ ULONG R5;
+ ULONG R6;
+ ULONG R7;
+ ULONG R8;
+ ULONG R9;
+ ULONG R10;
+ ULONG R11;
+ ULONG R12;
+ ULONG R13;
+ ULONG R14;
+ ULONG R15;
+
+ /* This section is specified/returned if the ContextFlags word contains */
+ /* the flag CONTEXT_CONTROL. */
+
+ /* N.B. The registers r15 and ra are defined in the integer section, */
+ /* but are considered part of the control context rather than part of */
+ /* the integer context. */
+
+ ULONG Fir;
+ ULONG Psr;
+
+#if !defined(SH3e) && !defined(SH4)
+ ULONG OldStuff[2];
+ DEBUG_REGISTERS DebugRegisters;
+#else
+ ULONG Fpscr;
+ ULONG Fpul;
+ ULONG FRegs[16];
+#if defined(SH4)
+ ULONG xFRegs[16];
+#endif
+#endif
+} CONTEXT;
+
+#elif defined(_MIPS_)
+
+/* The following flags control the contents of the CONTEXT structure. */
+
+#define CONTEXT_R4000 0x00010000 /* r4000 context */
+
+#define CONTEXT_CONTROL (CONTEXT_R4000 | 0x00000001L)
+#define CONTEXT_FLOATING_POINT (CONTEXT_R4000 | 0x00000002L)
+#define CONTEXT_INTEGER (CONTEXT_R4000 | 0x00000004L)
+
+#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_FLOATING_POINT | CONTEXT_INTEGER)
+
+/* Context Frame */
+
+/* N.B. This frame must be exactly a multiple of 16 bytes in length. */
+
+/* This frame has a several purposes: 1) it is used as an argument to */
+/* NtContinue, 2) it is used to constuct a call frame for APC delivery, */
+/* 3) it is used to construct a call frame for exception dispatching */
+/* in user mode, and 4) it is used in the user level thread creation */
+/* routines. */
+
+/* The layout of the record conforms to a standard call frame. */
+
+
+typedef struct _CONTEXT {
+
+ /* This section is always present and is used as an argument build */
+ /* area. */
+
+ DWORD Argument[4];
+
+ /* This section is specified/returned if the ContextFlags word contains */
+ /* the flag CONTEXT_FLOATING_POINT. */
+
+ DWORD FltF0;
+ DWORD FltF1;
+ DWORD FltF2;
+ DWORD FltF3;
+ DWORD FltF4;
+ DWORD FltF5;
+ DWORD FltF6;
+ DWORD FltF7;
+ DWORD FltF8;
+ DWORD FltF9;
+ DWORD FltF10;
+ DWORD FltF11;
+ DWORD FltF12;
+ DWORD FltF13;
+ DWORD FltF14;
+ DWORD FltF15;
+ DWORD FltF16;
+ DWORD FltF17;
+ DWORD FltF18;
+ DWORD FltF19;
+ DWORD FltF20;
+ DWORD FltF21;
+ DWORD FltF22;
+ DWORD FltF23;
+ DWORD FltF24;
+ DWORD FltF25;
+ DWORD FltF26;
+ DWORD FltF27;
+ DWORD FltF28;
+ DWORD FltF29;
+ DWORD FltF30;
+ DWORD FltF31;
+
+ /* This section is specified/returned if the ContextFlags word contains */
+ /* the flag CONTEXT_INTEGER. */
+
+ /* N.B. The registers gp, sp, and ra are defined in this section, but are */
+ /* considered part of the control context rather than part of the integer */
+ /* context. */
+
+ /* N.B. Register zero is not stored in the frame. */
+
+ DWORD IntZero;
+ DWORD IntAt;
+ DWORD IntV0;
+ DWORD IntV1;
+ DWORD IntA0;
+ DWORD IntA1;
+ DWORD IntA2;
+ DWORD IntA3;
+ DWORD IntT0;
+ DWORD IntT1;
+ DWORD IntT2;
+ DWORD IntT3;
+ DWORD IntT4;
+ DWORD IntT5;
+ DWORD IntT6;
+ DWORD IntT7;
+ DWORD IntS0;
+ DWORD IntS1;
+ DWORD IntS2;
+ DWORD IntS3;
+ DWORD IntS4;
+ DWORD IntS5;
+ DWORD IntS6;
+ DWORD IntS7;
+ DWORD IntT8;
+ DWORD IntT9;
+ DWORD IntK0;
+ DWORD IntK1;
+ DWORD IntGp;
+ DWORD IntSp;
+ DWORD IntS8;
+ DWORD IntRa;
+ DWORD IntLo;
+ DWORD IntHi;
+
+ /* This section is specified/returned if the ContextFlags word contains */
+ /* the flag CONTEXT_FLOATING_POINT. */
+
+ DWORD Fsr;
+
+ /* This section is specified/returned if the ContextFlags word contains */
+ /* the flag CONTEXT_CONTROL. */
+
+ /* N.B. The registers gp, sp, and ra are defined in the integer section, */
+ /* but are considered part of the control context rather than part of */
+ /* the integer context. */
+
+ DWORD Fir;
+ DWORD Psr;
+
+ /* The flags values within this flag control the contents of */
+ /* a CONTEXT record. */
+
+ /* If the context record is used as an input parameter, then */
+ /* for each portion of the context record controlled by a flag */
+ /* whose value is set, it is assumed that that portion of the */
+ /* context record contains valid context. If the context record */
+ /* is being used to modify a thread's context, then only that */
+ /* portion of the threads context will be modified. */
+
+ /* If the context record is used as an IN OUT parameter to capture */
+ /* the context of a thread, then only those portions of the thread's */
+ /* context corresponding to set flags will be returned. */
+
+ /* The context record is never used as an OUT only parameter. */
+
+ DWORD ContextFlags;
+
+ DWORD Fill[2];
+
+} CONTEXT;
+#elif defined(ARM)
+
+#ifndef PAGE_SIZE
+#define PAGE_SIZE 0x1000 // FIXME: This should probably go elsewhere
+#endif
+
+/* The following flags control the contents of the CONTEXT structure. */
+
+#define CONTEXT_ARM 0x0000040
+#define CONTEXT_CONTROL (CONTEXT_ARM | 0x00000001L)
+#define CONTEXT_INTEGER (CONTEXT_ARM | 0x00000002L)
+
+#define CONTEXT_FULL (CONTEXT_CONTROL | CONTEXT_INTEGER)
+
+typedef struct _CONTEXT {
+ /* The flags values within this flag control the contents of
+ a CONTEXT record.
+
+ If the context record is used as an input parameter, then
+ for each portion of the context record controlled by a flag
+ whose value is set, it is assumed that that portion of the
+ context record contains valid context. If the context record
+ is being used to modify a thread's context, then only that
+ portion of the threads context will be modified.
+
+ If the context record is used as an IN OUT parameter to capture
+ the context of a thread, then only those portions of the thread's
+ context corresponding to set flags will be returned.
+
+ The context record is never used as an OUT only parameter. */
+
+ ULONG ContextFlags;
+
+ /* This section is specified/returned if the ContextFlags word contains
+ the flag CONTEXT_INTEGER. */
+ ULONG R0;
+ ULONG R1;
+ ULONG R2;
+ ULONG R3;
+ ULONG R4;
+ ULONG R5;
+ ULONG R6;
+ ULONG R7;
+ ULONG R8;
+ ULONG R9;
+ ULONG R10;
+ ULONG R11;
+ ULONG R12;
+
+ ULONG Sp;
+ ULONG Lr;
+ ULONG Pc;
+ ULONG Psr;
+} CONTEXT;
+
+#else
+#error "undefined processor type"
+#endif
+typedef CONTEXT *PCONTEXT,*LPCONTEXT;
+
+#define EXCEPTION_NONCONTINUABLE 1
+#define EXCEPTION_MAXIMUM_PARAMETERS 15
+
+typedef struct _EXCEPTION_RECORD {
+ DWORD ExceptionCode;
+ DWORD ExceptionFlags;
+ struct _EXCEPTION_RECORD *ExceptionRecord;
+ PVOID ExceptionAddress;
+ DWORD NumberParameters;
+ ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
+} EXCEPTION_RECORD, *PEXCEPTION_RECORD;
+
+typedef struct _EXCEPTION_RECORD32 {
+ DWORD ExceptionCode;
+ DWORD ExceptionFlags;
+ DWORD ExceptionRecord;
+ DWORD ExceptionAddress;
+ DWORD NumberParameters;
+ DWORD ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
+} EXCEPTION_RECORD32,*PEXCEPTION_RECORD32;
+
+typedef struct _EXCEPTION_RECORD64 {
+ DWORD ExceptionCode;
+ DWORD ExceptionFlags;
+ DWORD64 ExceptionRecord;
+ DWORD64 ExceptionAddress;
+ DWORD NumberParameters;
+ DWORD __unusedAlignment;
+ DWORD64 ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
+} EXCEPTION_RECORD64,*PEXCEPTION_RECORD64;
+
+typedef struct _EXCEPTION_POINTERS {
+ PEXCEPTION_RECORD ExceptionRecord;
+ PCONTEXT ContextRecord;
+} EXCEPTION_POINTERS,*PEXCEPTION_POINTERS, *LPEXCEPTION_POINTERS;
+
+#ifdef _M_PPC
+#define LARGE_INTEGER_ORDER(x) x HighPart; DWORD LowPart;
+#else
+#define LARGE_INTEGER_ORDER(x) DWORD LowPart; x HighPart;
+#endif
+
+typedef union _LARGE_INTEGER {
+#if ! defined(NONAMELESSUNION) || defined(__cplusplus)
+ _ANONYMOUS_STRUCT struct {
+ LARGE_INTEGER_ORDER(LONG)
+ };
+#endif /* NONAMELESSUNION */
+ struct {
+ LARGE_INTEGER_ORDER(LONG)
+ } u;
+ LONGLONG QuadPart;
+} LARGE_INTEGER, *PLARGE_INTEGER;
+typedef union _ULARGE_INTEGER {
+#if ! defined(NONAMELESSUNION) || defined(__cplusplus)
+ _ANONYMOUS_STRUCT struct {
+ LARGE_INTEGER_ORDER(DWORD)
+ };
+#endif /* NONAMELESSUNION */
+ struct {
+ LARGE_INTEGER_ORDER(DWORD)
+ } u;
+ ULONGLONG QuadPart;
+} ULARGE_INTEGER, *PULARGE_INTEGER;
+typedef struct _LUID {
+ LARGE_INTEGER_ORDER(LONG)
+} LUID, *PLUID;
+
+#include <pshpack4.h>
+
+typedef struct _LUID_AND_ATTRIBUTES {
+ LUID Luid;
+ DWORD Attributes;
+} LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES;
+typedef LUID_AND_ATTRIBUTES LUID_AND_ATTRIBUTES_ARRAY[ANYSIZE_ARRAY];
+typedef LUID_AND_ATTRIBUTES_ARRAY *PLUID_AND_ATTRIBUTES_ARRAY;
+
+#include <poppack.h>
+
+typedef struct _PRIVILEGE_SET {
+ DWORD PrivilegeCount;
+ DWORD Control;
+ LUID_AND_ATTRIBUTES Privilege[ANYSIZE_ARRAY];
+} PRIVILEGE_SET,*PPRIVILEGE_SET;
+
+typedef struct _SECURITY_ATTRIBUTES {
+ DWORD nLength;
+ LPVOID lpSecurityDescriptor;
+ BOOL bInheritHandle;
+} SECURITY_ATTRIBUTES,*PSECURITY_ATTRIBUTES,*LPSECURITY_ATTRIBUTES;
+
+typedef enum _SECURITY_IMPERSONATION_LEVEL {
+ SecurityAnonymous,
+ SecurityIdentification,
+ SecurityImpersonation,
+ SecurityDelegation
+} SECURITY_IMPERSONATION_LEVEL,*PSECURITY_IMPERSONATION_LEVEL;
+
+typedef BOOLEAN SECURITY_CONTEXT_TRACKING_MODE,*PSECURITY_CONTEXT_TRACKING_MODE;
+
+typedef struct _SECURITY_QUALITY_OF_SERVICE {
+ DWORD Length;
+ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
+ SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode;
+ BOOLEAN EffectiveOnly;
+} SECURITY_QUALITY_OF_SERVICE,*PSECURITY_QUALITY_OF_SERVICE;
+
+typedef PVOID PACCESS_TOKEN;
+
+typedef struct _SE_IMPERSONATION_STATE {
+ PACCESS_TOKEN Token;
+ BOOLEAN CopyOnOpen;
+ BOOLEAN EffectiveOnly;
+ SECURITY_IMPERSONATION_LEVEL Level;
+} SE_IMPERSONATION_STATE,*PSE_IMPERSONATION_STATE;
+
+typedef struct _SID_IDENTIFIER_AUTHORITY {
+ BYTE Value[6];
+} SID_IDENTIFIER_AUTHORITY,*PSID_IDENTIFIER_AUTHORITY,*LPSID_IDENTIFIER_AUTHORITY;
+
+typedef PVOID PSID;
+
+typedef struct _SID {
+ BYTE Revision;
+ BYTE SubAuthorityCount;
+ SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
+ DWORD SubAuthority[ANYSIZE_ARRAY];
+} SID, *PISID;
+
+#define SECURITY_MIN_SID_SIZE (sizeof(SID))
+#define SECURITY_MAX_SID_SIZE (FIELD_OFFSET(SID, SubAuthority) + SID_MAX_SUB_AUTHORITIES * sizeof(DWORD))
+
+typedef struct _SID_AND_ATTRIBUTES {
+ PSID Sid;
+ DWORD Attributes;
+} SID_AND_ATTRIBUTES, *PSID_AND_ATTRIBUTES;
+typedef SID_AND_ATTRIBUTES SID_AND_ATTRIBUTES_ARRAY[ANYSIZE_ARRAY];
+typedef SID_AND_ATTRIBUTES_ARRAY *PSID_AND_ATTRIBUTES_ARRAY;
+
+typedef struct _TOKEN_SOURCE {
+ CHAR SourceName[TOKEN_SOURCE_LENGTH];
+ LUID SourceIdentifier;
+} TOKEN_SOURCE,*PTOKEN_SOURCE;
+
+typedef struct _TOKEN_CONTROL {
+ LUID TokenId;
+ LUID AuthenticationId;
+ LUID ModifiedId;
+ TOKEN_SOURCE TokenSource;
+} TOKEN_CONTROL,*PTOKEN_CONTROL;
+
+typedef struct _TOKEN_DEFAULT_DACL {
+ PACL DefaultDacl;
+} TOKEN_DEFAULT_DACL,*PTOKEN_DEFAULT_DACL;
+
+typedef struct _TOKEN_GROUPS {
+ DWORD GroupCount;
+ SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY];
+} TOKEN_GROUPS,*PTOKEN_GROUPS,*LPTOKEN_GROUPS;
+
+typedef struct _TOKEN_GROUPS_AND_PRIVILEGES {
+ DWORD SidCount;
+ DWORD SidLength;
+ PSID_AND_ATTRIBUTES Sids;
+ DWORD RestrictedSidCount;
+ DWORD RestrictedSidLength;
+ PSID_AND_ATTRIBUTES RestrictedSids;
+ DWORD PrivilegeCount;
+ DWORD PrivilegeLength;
+ PLUID_AND_ATTRIBUTES Privileges;
+ LUID AuthenticationId;
+} TOKEN_GROUPS_AND_PRIVILEGES, *PTOKEN_GROUPS_AND_PRIVILEGES;
+
+typedef struct _TOKEN_ORIGIN {
+ LUID OriginatingLogonSession;
+} TOKEN_ORIGIN, *PTOKEN_ORIGIN;
+
+typedef struct _TOKEN_OWNER {
+ PSID Owner;
+} TOKEN_OWNER,*PTOKEN_OWNER;
+
+typedef struct _TOKEN_PRIMARY_GROUP {
+ PSID PrimaryGroup;
+} TOKEN_PRIMARY_GROUP,*PTOKEN_PRIMARY_GROUP;
+
+typedef struct _TOKEN_PRIVILEGES {
+ DWORD PrivilegeCount;
+ LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY];
+} TOKEN_PRIVILEGES,*PTOKEN_PRIVILEGES,*LPTOKEN_PRIVILEGES;
+
+typedef enum tagTOKEN_TYPE {
+ TokenPrimary = 1,
+ TokenImpersonation
+} TOKEN_TYPE,*PTOKEN_TYPE;
+
+#include <pshpack4.h>
+typedef struct _TOKEN_STATISTICS {
+ LUID TokenId;
+ LUID AuthenticationId;
+ LARGE_INTEGER ExpirationTime;
+ TOKEN_TYPE TokenType;
+ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
+ DWORD DynamicCharged;
+ DWORD DynamicAvailable;
+ DWORD GroupCount;
+ DWORD PrivilegeCount;
+ LUID ModifiedId;
+} TOKEN_STATISTICS, *PTOKEN_STATISTICS;
+#include <poppack.h>
+
+typedef struct _TOKEN_USER {
+ SID_AND_ATTRIBUTES User;
+} TOKEN_USER, *PTOKEN_USER;
+
+typedef DWORD SECURITY_INFORMATION,*PSECURITY_INFORMATION;
+typedef WORD SECURITY_DESCRIPTOR_CONTROL,*PSECURITY_DESCRIPTOR_CONTROL;
+
+#ifndef _SECURITY_ATTRIBUTES_
+#define _SECURITY_ATTRIBUTES_
+typedef struct _SECURITY_DESCRIPTOR {
+ BYTE Revision;
+ BYTE Sbz1;
+ SECURITY_DESCRIPTOR_CONTROL Control;
+ PSID Owner;
+ PSID Group;
+ PACL Sacl;
+ PACL Dacl;
+} SECURITY_DESCRIPTOR, *PISECURITY_DESCRIPTOR;
+typedef PVOID PSECURITY_DESCRIPTOR;
+#endif
+
+typedef struct _SECURITY_DESCRIPTOR_RELATIVE {
+ BYTE Revision;
+ BYTE Sbz1;
+ SECURITY_DESCRIPTOR_CONTROL Control;
+ DWORD Owner;
+ DWORD Group;
+ DWORD Sacl;
+ DWORD Dacl;
+} SECURITY_DESCRIPTOR_RELATIVE, *PISECURITY_DESCRIPTOR_RELATIVE;
+
+typedef enum _TOKEN_INFORMATION_CLASS {
+ TokenUser = 1,
+ TokenGroups,
+ TokenPrivileges,
+ TokenOwner,
+ TokenPrimaryGroup,
+ TokenDefaultDacl,
+ TokenSource,
+ TokenType,
+ TokenImpersonationLevel,
+ TokenStatistics,
+ TokenRestrictedSids,
+ TokenSessionId,
+ TokenGroupsAndPrivileges,
+ TokenSessionReference,
+ TokenSandBoxInert,
+ TokenAuditPolicy,
+ TokenOrigin,
+ TokenElevationType,
+ TokenLinkedToken,
+ TokenElevation,
+ TokenHasRestrictions,
+ TokenAccessInformation,
+ TokenVirtualizationAllowed,
+ TokenVirtualizationEnabled,
+ TokenIntegrityLevel,
+ TokenUIAccess,
+ TokenMandatoryPolicy,
+ TokenLogonSid,
+ MaxTokenInfoClass
+} TOKEN_INFORMATION_CLASS;
+
+typedef enum _SID_NAME_USE {
+ SidTypeUser=1,
+ SidTypeGroup,
+ SidTypeDomain,
+ SidTypeAlias,
+ SidTypeWellKnownGroup,
+ SidTypeDeletedAccount,
+ SidTypeInvalid,
+ SidTypeUnknown,
+ SidTypeComputer,
+ SidTypeLabel
+} SID_NAME_USE,*PSID_NAME_USE;
+
+typedef struct _QUOTA_LIMITS {
+ SIZE_T PagedPoolLimit;
+ SIZE_T NonPagedPoolLimit;
+ SIZE_T MinimumWorkingSetSize;
+ SIZE_T MaximumWorkingSetSize;
+ SIZE_T PagefileLimit;
+ LARGE_INTEGER TimeLimit;
+} QUOTA_LIMITS,*PQUOTA_LIMITS;
+
+typedef struct _IO_COUNTERS {
+ ULONGLONG ReadOperationCount;
+ ULONGLONG WriteOperationCount;
+ ULONGLONG OtherOperationCount;
+ ULONGLONG ReadTransferCount;
+ ULONGLONG WriteTransferCount;
+ ULONGLONG OtherTransferCount;
+} IO_COUNTERS, *PIO_COUNTERS;
+
+typedef struct _FILE_NOTIFY_INFORMATION {
+ DWORD NextEntryOffset;
+ DWORD Action;
+ DWORD FileNameLength;
+ WCHAR FileName[1];
+} FILE_NOTIFY_INFORMATION,*PFILE_NOTIFY_INFORMATION;
+
+typedef struct _TAPE_ERASE {
+ DWORD Type;
+ BOOLEAN Immediate;
+} TAPE_ERASE, *PTAPE_ERASE;
+
+typedef struct _TAPE_GET_DRIVE_PARAMETERS {
+ BOOLEAN ECC;
+ BOOLEAN Compression;
+ BOOLEAN DataPadding;
+ BOOLEAN ReportSetmarks;
+ DWORD DefaultBlockSize;
+ DWORD MaximumBlockSize;
+ DWORD MinimumBlockSize;
+ DWORD MaximumPartitionCount;
+ DWORD FeaturesLow;
+ DWORD FeaturesHigh;
+ DWORD EOTWarningZoneSize;
+} TAPE_GET_DRIVE_PARAMETERS, *PTAPE_GET_DRIVE_PARAMETERS;
+
+typedef struct _TAPE_GET_MEDIA_PARAMETERS {
+ LARGE_INTEGER Capacity;
+ LARGE_INTEGER Remaining;
+ DWORD BlockSize;
+ DWORD PartitionCount;
+ BOOLEAN WriteProtected;
+} TAPE_GET_MEDIA_PARAMETERS, *PTAPE_GET_MEDIA_PARAMETERS;
+
+typedef struct _TAPE_GET_POSITION {
+ ULONG Type;
+ ULONG Partition;
+ LARGE_INTEGER Offset;
+} TAPE_GET_POSITION, *PTAPE_GET_POSITION;
+
+typedef struct _TAPE_PREPARE {
+ DWORD Operation;
+ BOOLEAN Immediate;
+} TAPE_PREPARE, *PTAPE_PREPARE;
+
+typedef struct _TAPE_SET_DRIVE_PARAMETERS {
+ BOOLEAN ECC;
+ BOOLEAN Compression;
+ BOOLEAN DataPadding;
+ BOOLEAN ReportSetmarks;
+ DWORD EOTWarningZoneSize;
+} TAPE_SET_DRIVE_PARAMETERS, *PTAPE_SET_DRIVE_PARAMETERS;
+
+typedef struct _TAPE_SET_MEDIA_PARAMETERS {
+ DWORD BlockSize;
+} TAPE_SET_MEDIA_PARAMETERS,*PTAPE_SET_MEDIA_PARAMETERS;
+
+typedef struct _TAPE_SET_POSITION {
+ DWORD Method;
+ DWORD Partition;
+ LARGE_INTEGER Offset;
+ BOOLEAN Immediate;
+} TAPE_SET_POSITION, *PTAPE_SET_POSITION;
+
+typedef struct _TAPE_WRITE_MARKS {
+ DWORD Type;
+ DWORD Count;
+ BOOLEAN Immediate;
+} TAPE_WRITE_MARKS, *PTAPE_WRITE_MARKS;
+
+typedef struct _TAPE_CREATE_PARTITION {
+ DWORD Method;
+ DWORD Count;
+ DWORD Size;
+} TAPE_CREATE_PARTITION, *PTAPE_CREATE_PARTITION;
+
+typedef struct _MEMORY_BASIC_INFORMATION {
+ PVOID BaseAddress;
+ PVOID AllocationBase;
+ DWORD AllocationProtect;
+ SIZE_T RegionSize;
+ DWORD State;
+ DWORD Protect;
+ DWORD Type;
+} MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;
+
+typedef struct _MESSAGE_RESOURCE_ENTRY {
+ WORD Length;
+ WORD Flags;
+ BYTE Text[1];
+} MESSAGE_RESOURCE_ENTRY, *PMESSAGE_RESOURCE_ENTRY;
+
+typedef struct _MESSAGE_RESOURCE_BLOCK {
+ DWORD LowId;
+ DWORD HighId;
+ DWORD OffsetToEntries;
+} MESSAGE_RESOURCE_BLOCK, *PMESSAGE_RESOURCE_BLOCK;
+
+typedef struct _MESSAGE_RESOURCE_DATA {
+ DWORD NumberOfBlocks;
+ MESSAGE_RESOURCE_BLOCK Blocks[1];
+} MESSAGE_RESOURCE_DATA,*PMESSAGE_RESOURCE_DATA;
+
+typedef struct _LIST_ENTRY {
+ struct _LIST_ENTRY *Flink;
+ struct _LIST_ENTRY *Blink;
+} LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY;
+
+typedef struct _LIST_ENTRY32 {
+ DWORD Flink;
+ DWORD Blink;
+} LIST_ENTRY32,*PLIST_ENTRY32;
+
+typedef struct _LIST_ENTRY64 {
+ ULONGLONG Flink;
+ ULONGLONG Blink;
+} LIST_ENTRY64,*PLIST_ENTRY64;
+
+typedef struct _SINGLE_LIST_ENTRY {
+ struct _SINGLE_LIST_ENTRY *Next;
+} SINGLE_LIST_ENTRY,*PSINGLE_LIST_ENTRY;
+
+//
+// Slist Header
+//
+#ifndef _SLIST_HEADER_
+#define _SLIST_HEADER_
+
+#if defined(_WIN64)
+
+typedef struct DECLSPEC_ALIGN(16) _SLIST_ENTRY {
+ struct _SLIST_ENTRY *Next;
+} SLIST_ENTRY, *PSLIST_ENTRY;
+
+typedef struct _SLIST_ENTRY32 {
+ DWORD Next;
+} SLIST_ENTRY32, *PSLIST_ENTRY32;
+
+typedef union DECLSPEC_ALIGN(16) _SLIST_HEADER {
+ _ANONYMOUS_STRUCT struct {
+ ULONGLONG Alignment;
+ ULONGLONG Region;
+ } DUMMYSTRUCTNAME;
+ struct {
+ ULONGLONG Depth:16;
+ ULONGLONG Sequence:9;
+ ULONGLONG NextEntry:39;
+ ULONGLONG HeaderType:1;
+ ULONGLONG Init:1;
+ ULONGLONG Reserved:59;
+ ULONGLONG Region:3;
+ } Header8;
+ struct {
+ ULONGLONG Depth:16;
+ ULONGLONG Sequence:48;
+ ULONGLONG HeaderType:1;
+ ULONGLONG Init:1;
+ ULONGLONG Reserved:2;
+ ULONGLONG NextEntry:60;
+ } Header16;
+ struct {
+ ULONGLONG Depth:16;
+ ULONGLONG Sequence:48;
+ ULONGLONG HeaderType:1;
+ ULONGLONG Reserved:3;
+ ULONGLONG NextEntry:60;
+ } HeaderX64;
+} SLIST_HEADER, *PSLIST_HEADER;
+
+typedef union _SLIST_HEADER32{
+ ULONGLONG Alignment;
+ _ANONYMOUS_STRUCT struct {
+ SLIST_ENTRY32 Next;
+ WORD Depth;
+ WORD Sequence;
+ } DUMMYSTRUCTNAME;
+} SLIST_HEADER32, *PSLIST_HEADER32;
+
+#else
+
+#define SLIST_ENTRY SINGLE_LIST_ENTRY
+#define _SLIST_ENTRY _SINGLE_LIST_ENTRY
+#define PSLIST_ENTRY PSINGLE_LIST_ENTRY
+
+typedef SLIST_ENTRY SLIST_ENTRY32, *PSLIST_ENTRY32;
+
+typedef union _SLIST_HEADER {
+ ULONGLONG Alignment;
+ _ANONYMOUS_STRUCT struct {
+ SLIST_ENTRY Next;
+ WORD Depth;
+ WORD Sequence;
+ } DUMMYSTRUCTNAME;
+} SLIST_HEADER, *PSLIST_HEADER;
+
+typedef SLIST_HEADER SLIST_HEADER32, *PSLIST_HEADER32;
+
+#endif /* defined(_WIN64) */
+
+#endif /* _SLIST_HEADER_ */
+
+NTSYSAPI
+VOID
+NTAPI
+RtlInitializeSListHead (
+ IN PSLIST_HEADER ListHead
+ );
+
+NTSYSAPI
+PSLIST_ENTRY
+NTAPI
+RtlFirstEntrySList (
+ IN const SLIST_HEADER *ListHead
+ );
+
+NTSYSAPI
+PSLIST_ENTRY
+NTAPI
+RtlInterlockedPopEntrySList (
+ IN PSLIST_HEADER ListHead
+ );
+
+NTSYSAPI
+PSLIST_ENTRY
+NTAPI
+RtlInterlockedPushEntrySList (
+ IN PSLIST_HEADER ListHead,
+ IN PSLIST_ENTRY ListEntry
+ );
+
+NTSYSAPI
+PSLIST_ENTRY
+NTAPI
+RtlInterlockedFlushSList (
+ IN PSLIST_HEADER ListHead
+ );
+
+NTSYSAPI
+WORD
+NTAPI
+RtlQueryDepthSList (
+ IN PSLIST_HEADER ListHead
+ );
+
+typedef struct _RTL_CRITICAL_SECTION_DEBUG {
+ WORD Type;
+ WORD CreatorBackTraceIndex;
+ struct _RTL_CRITICAL_SECTION *CriticalSection;
+ LIST_ENTRY ProcessLocksList;
+ DWORD EntryCount;
+ DWORD ContentionCount;
+ DWORD Flags;
+ WORD CreatorBackTraceIndexHigh;
+ WORD SpareWORD;
+} RTL_CRITICAL_SECTION_DEBUG, *PRTL_CRITICAL_SECTION_DEBUG, RTL_RESOURCE_DEBUG, *PRTL_RESOURCE_DEBUG;
+
+#include "pshpack8.h"
+typedef struct _RTL_CRITICAL_SECTION {
+ PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
+ LONG LockCount;
+ LONG RecursionCount;
+ HANDLE OwningThread;
+ HANDLE LockSemaphore;
+ ULONG_PTR SpinCount;
+} RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;
+#include "poppack.h"
+
+NTSYSAPI
+WORD
+NTAPI
+RtlCaptureStackBackTrace(
+ IN DWORD FramesToSkip,
+ IN DWORD FramesToCapture,
+ OUT PVOID *BackTrace,
+ OUT PDWORD BackTraceHash OPTIONAL
+);
+
+NTSYSAPI
+VOID
+NTAPI
+RtlCaptureContext(
+ PCONTEXT ContextRecord
+);
+
+NTSYSAPI
+PVOID
+NTAPI
+RtlPcToFileHeader(
+ IN PVOID PcValue,
+ PVOID* BaseOfImage
+);
+
+NTSYSAPI
+VOID
+NTAPI
+RtlUnwind (
+ IN PVOID TargetFrame OPTIONAL,
+ IN PVOID TargetIp OPTIONAL,
+ IN PEXCEPTION_RECORD ExceptionRecord OPTIONAL,
+ IN PVOID ReturnValue
+ );
+
+#define RTL_SRWLOCK_INIT {0}
+
+typedef struct _RTL_SRWLOCK {
+ PVOID Ptr;
+} RTL_SRWLOCK, *PRTL_SRWLOCK;
+
+#define RTL_CONDITION_VARIABLE_INIT {0}
+#define RTL_CONDITION_VARIABLE_LOCKMODE_SHARED 0x1
+
+typedef struct _RTL_CONDITION_VARIABLE {
+ PVOID Ptr;
+} RTL_CONDITION_VARIABLE, *PRTL_CONDITION_VARIABLE;
+
+typedef LONG
+(NTAPI *PVECTORED_EXCEPTION_HANDLER)(
+ struct _EXCEPTION_POINTERS *ExceptionInfo
+);
+
+typedef struct _PROCESSOR_NUMBER {
+ WORD Group;
+ BYTE Number;
+ BYTE Reserved;
+} PROCESSOR_NUMBER, *PPROCESSOR_NUMBER;
+
+typedef struct _GROUP_AFFINITY {
+ KAFFINITY Mask;
+ WORD Group;
+ WORD Reserved[3];
+} GROUP_AFFINITY, *PGROUP_AFFINITY;
+
+typedef struct _EVENTLOGRECORD {
+ DWORD Length;
+ DWORD Reserved;
+ DWORD RecordNumber;
+ DWORD TimeGenerated;
+ DWORD TimeWritten;
+ DWORD EventID;
+ WORD EventType;
+ WORD NumStrings;
+ WORD EventCategory;
+ WORD ReservedFlags;
+ DWORD ClosingRecordNumber;
+ DWORD StringOffset;
+ DWORD UserSidLength;
+ DWORD UserSidOffset;
+ DWORD DataLength;
+ DWORD DataOffset;
+} EVENTLOGRECORD, *PEVENTLOGRECORD;
+
+typedef struct _OSVERSIONINFOA {
+ DWORD dwOSVersionInfoSize;
+ DWORD dwMajorVersion;
+ DWORD dwMinorVersion;
+ DWORD dwBuildNumber;
+ DWORD dwPlatformId;
+ CHAR szCSDVersion[128];
+} OSVERSIONINFOA, *POSVERSIONINFOA, *LPOSVERSIONINFOA;
+
+typedef struct _OSVERSIONINFOW {
+ DWORD dwOSVersionInfoSize;
+ DWORD dwMajorVersion;
+ DWORD dwMinorVersion;
+ DWORD dwBuildNumber;
+ DWORD dwPlatformId;
+ WCHAR szCSDVersion[128];
+} OSVERSIONINFOW, *POSVERSIONINFOW, *LPOSVERSIONINFOW, RTL_OSVERSIONINFOW, *PRTL_OSVERSIONINFOW;
+
+typedef struct _OSVERSIONINFOEXA {
+ DWORD dwOSVersionInfoSize;
+ DWORD dwMajorVersion;
+ DWORD dwMinorVersion;
+ DWORD dwBuildNumber;
+ DWORD dwPlatformId;
+ CHAR szCSDVersion[128];
+ WORD wServicePackMajor;
+ WORD wServicePackMinor;
+ WORD wSuiteMask;
+ BYTE wProductType;
+ BYTE wReserved;
+} OSVERSIONINFOEXA, *POSVERSIONINFOEXA, *LPOSVERSIONINFOEXA;
+
+typedef struct _OSVERSIONINFOEXW {
+ DWORD dwOSVersionInfoSize;
+ DWORD dwMajorVersion;
+ DWORD dwMinorVersion;
+ DWORD dwBuildNumber;
+ DWORD dwPlatformId;
+ WCHAR szCSDVersion[128];
+ WORD wServicePackMajor;
+ WORD wServicePackMinor;
+ WORD wSuiteMask;
+ BYTE wProductType;
+ BYTE wReserved;
+} OSVERSIONINFOEXW, *POSVERSIONINFOEXW, *LPOSVERSIONINFOEXW, RTL_OSVERSIONINFOEXW, *PRTL_OSVERSIONINFOEXW;
+
+#include <pshpack2.h>
+
+typedef struct _IMAGE_VXD_HEADER {
+ WORD e32_magic;
+ BYTE e32_border;
+ BYTE e32_worder;
+ DWORD e32_level;
+ WORD e32_cpu;
+ WORD e32_os;
+ DWORD e32_ver;
+ DWORD e32_mflags;
+ DWORD e32_mpages;
+ DWORD e32_startobj;
+ DWORD e32_eip;
+ DWORD e32_stackobj;
+ DWORD e32_esp;
+ DWORD e32_pagesize;
+ DWORD e32_lastpagesize;
+ DWORD e32_fixupsize;
+ DWORD e32_fixupsum;
+ DWORD e32_ldrsize;
+ DWORD e32_ldrsum;
+ DWORD e32_objtab;
+ DWORD e32_objcnt;
+ DWORD e32_objmap;
+ DWORD e32_itermap;
+ DWORD e32_rsrctab;
+ DWORD e32_rsrccnt;
+ DWORD e32_restab;
+ DWORD e32_enttab;
+ DWORD e32_dirtab;
+ DWORD e32_dircnt;
+ DWORD e32_fpagetab;
+ DWORD e32_frectab;
+ DWORD e32_impmod;
+ DWORD e32_impmodcnt;
+ DWORD e32_impproc;
+ DWORD e32_pagesum;
+ DWORD e32_datapage;
+ DWORD e32_preload;
+ DWORD e32_nrestab;
+ DWORD e32_cbnrestab;
+ DWORD e32_nressum;
+ DWORD e32_autodata;
+ DWORD e32_debuginfo;
+ DWORD e32_debuglen;
+ DWORD e32_instpreload;
+ DWORD e32_instdemand;
+ DWORD e32_heapsize;
+ BYTE e32_res3[12];
+ DWORD e32_winresoff;
+ DWORD e32_winreslen;
+ WORD e32_devid;
+ WORD e32_ddkver;
+} IMAGE_VXD_HEADER, *PIMAGE_VXD_HEADER;
+
+typedef struct _IMAGE_DOS_HEADER {
+ WORD e_magic;
+ WORD e_cblp;
+ WORD e_cp;
+ WORD e_crlc;
+ WORD e_cparhdr;
+ WORD e_minalloc;
+ WORD e_maxalloc;
+ WORD e_ss;
+ WORD e_sp;
+ WORD e_csum;
+ WORD e_ip;
+ WORD e_cs;
+ WORD e_lfarlc;
+ WORD e_ovno;
+ WORD e_res[4];
+ WORD e_oemid;
+ WORD e_oeminfo;
+ WORD e_res2[10];
+ LONG e_lfanew;
+} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
+
+typedef struct _IMAGE_OS2_HEADER {
+ WORD ne_magic;
+ CHAR ne_ver;
+ CHAR ne_rev;
+ WORD ne_enttab;
+ WORD ne_cbenttab;
+ LONG ne_crc;
+ WORD ne_flags;
+ WORD ne_autodata;
+ WORD ne_heap;
+ WORD ne_stack;
+ LONG ne_csip;
+ LONG ne_sssp;
+ WORD ne_cseg;
+ WORD ne_cmod;
+ WORD ne_cbnrestab;
+ WORD ne_segtab;
+ WORD ne_rsrctab;
+ WORD ne_restab;
+ WORD ne_modtab;
+ WORD ne_imptab;
+ LONG ne_nrestab;
+ WORD ne_cmovent;
+ WORD ne_align;
+ WORD ne_cres;
+ BYTE ne_exetyp;
+ BYTE ne_flagsothers;
+ WORD ne_pretthunks;
+ WORD ne_psegrefbytes;
+ WORD ne_swaparea;
+ WORD ne_expver;
+} IMAGE_OS2_HEADER, *PIMAGE_OS2_HEADER;
+
+#include <poppack.h>
+
+typedef struct _IMAGE_FILE_HEADER {
+ WORD Machine;
+ WORD NumberOfSections;
+ DWORD TimeDateStamp;
+ DWORD PointerToSymbolTable;
+ DWORD NumberOfSymbols;
+ WORD SizeOfOptionalHeader;
+ WORD Characteristics;
+} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
+
+typedef struct _IMAGE_DATA_DIRECTORY {
+ DWORD VirtualAddress;
+ DWORD Size;
+} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
+
+typedef struct _IMAGE_OPTIONAL_HEADER32 {
+ WORD Magic;
+ BYTE MajorLinkerVersion;
+ BYTE MinorLinkerVersion;
+ DWORD SizeOfCode;
+ DWORD SizeOfInitializedData;
+ DWORD SizeOfUninitializedData;
+ DWORD AddressOfEntryPoint;
+ DWORD BaseOfCode;
+ DWORD BaseOfData;
+ DWORD ImageBase;
+ DWORD SectionAlignment;
+ DWORD FileAlignment;
+ WORD MajorOperatingSystemVersion;
+ WORD MinorOperatingSystemVersion;
+ WORD MajorImageVersion;
+ WORD MinorImageVersion;
+ WORD MajorSubsystemVersion;
+ WORD MinorSubsystemVersion;
+ DWORD Win32VersionValue;
+ DWORD SizeOfImage;
+ DWORD SizeOfHeaders;
+ DWORD CheckSum;
+ WORD Subsystem;
+ WORD DllCharacteristics;
+ DWORD SizeOfStackReserve;
+ DWORD SizeOfStackCommit;
+ DWORD SizeOfHeapReserve;
+ DWORD SizeOfHeapCommit;
+ DWORD LoaderFlags;
+ DWORD NumberOfRvaAndSizes;
+ IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
+} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;
+
+typedef struct _IMAGE_OPTIONAL_HEADER64 {
+ WORD Magic;
+ BYTE MajorLinkerVersion;
+ BYTE MinorLinkerVersion;
+ DWORD SizeOfCode;
+ DWORD SizeOfInitializedData;
+ DWORD SizeOfUninitializedData;
+ DWORD AddressOfEntryPoint;
+ DWORD BaseOfCode;
+ ULONGLONG ImageBase;
+ DWORD SectionAlignment;
+ DWORD FileAlignment;
+ WORD MajorOperatingSystemVersion;
+ WORD MinorOperatingSystemVersion;
+ WORD MajorImageVersion;
+ WORD MinorImageVersion;
+ WORD MajorSubsystemVersion;
+ WORD MinorSubsystemVersion;
+ DWORD Win32VersionValue;
+ DWORD SizeOfImage;
+ DWORD SizeOfHeaders;
+ DWORD CheckSum;
+ WORD Subsystem;
+ WORD DllCharacteristics;
+ ULONGLONG SizeOfStackReserve;
+ ULONGLONG SizeOfStackCommit;
+ ULONGLONG SizeOfHeapReserve;
+ ULONGLONG SizeOfHeapCommit;
+ DWORD LoaderFlags;
+ DWORD NumberOfRvaAndSizes;
+ IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
+} IMAGE_OPTIONAL_HEADER64, *PIMAGE_OPTIONAL_HEADER64;
+
+typedef struct _IMAGE_ROM_OPTIONAL_HEADER {
+ WORD Magic;
+ BYTE MajorLinkerVersion;
+ BYTE MinorLinkerVersion;
+ DWORD SizeOfCode;
+ DWORD SizeOfInitializedData;
+ DWORD SizeOfUninitializedData;
+ DWORD AddressOfEntryPoint;
+ DWORD BaseOfCode;
+ DWORD BaseOfData;
+ DWORD BaseOfBss;
+ DWORD GprMask;
+ DWORD CprMask[4];
+ DWORD GpValue;
+} IMAGE_ROM_OPTIONAL_HEADER, *PIMAGE_ROM_OPTIONAL_HEADER;
+
+typedef struct _IMAGE_NT_HEADERS32 {
+ DWORD Signature;
+ IMAGE_FILE_HEADER FileHeader;
+ IMAGE_OPTIONAL_HEADER32 OptionalHeader;
+} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
+
+typedef struct _IMAGE_NT_HEADERS64 {
+ DWORD Signature;
+ IMAGE_FILE_HEADER FileHeader;
+ IMAGE_OPTIONAL_HEADER64 OptionalHeader;
+} IMAGE_NT_HEADERS64, *PIMAGE_NT_HEADERS64;
+
+#ifdef _WIN64
+typedef IMAGE_OPTIONAL_HEADER64 IMAGE_OPTIONAL_HEADER;
+typedef PIMAGE_OPTIONAL_HEADER64 PIMAGE_OPTIONAL_HEADER;
+typedef IMAGE_NT_HEADERS64 IMAGE_NT_HEADERS;
+typedef PIMAGE_NT_HEADERS64 PIMAGE_NT_HEADERS;
+#else
+typedef IMAGE_OPTIONAL_HEADER32 IMAGE_OPTIONAL_HEADER;
+typedef PIMAGE_OPTIONAL_HEADER32 PIMAGE_OPTIONAL_HEADER;
+typedef IMAGE_NT_HEADERS32 IMAGE_NT_HEADERS;
+typedef PIMAGE_NT_HEADERS32 PIMAGE_NT_HEADERS;
+#endif
+
+typedef struct _IMAGE_ROM_HEADERS {
+ IMAGE_FILE_HEADER FileHeader;
+ IMAGE_ROM_OPTIONAL_HEADER OptionalHeader;
+} IMAGE_ROM_HEADERS, *PIMAGE_ROM_HEADERS;
+
+typedef struct _IMAGE_SECTION_HEADER {
+ BYTE Name[IMAGE_SIZEOF_SHORT_NAME];
+ union {
+ DWORD PhysicalAddress;
+ DWORD VirtualSize;
+ } Misc;
+ DWORD VirtualAddress;
+ DWORD SizeOfRawData;
+ DWORD PointerToRawData;
+ DWORD PointerToRelocations;
+ DWORD PointerToLinenumbers;
+ WORD NumberOfRelocations;
+ WORD NumberOfLinenumbers;
+ DWORD Characteristics;
+} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
+
+#include <pshpack2.h>
+
+typedef struct _IMAGE_SYMBOL {
+ union {
+ BYTE ShortName[8];
+ struct {
+ DWORD Short;
+ DWORD Long;
+ } Name;
+ PBYTE LongName[2];
+ } N;
+ DWORD Value;
+ SHORT SectionNumber;
+ WORD Type;
+ BYTE StorageClass;
+ BYTE NumberOfAuxSymbols;
+} IMAGE_SYMBOL, *PIMAGE_SYMBOL;
+
+typedef struct _IMAGE_LINENUMBER {
+ union {
+ DWORD SymbolTableIndex;
+ DWORD VirtualAddress;
+ } Type;
+ WORD Linenumber;
+} IMAGE_LINENUMBER, UNALIGNED *PIMAGE_LINENUMBER;
+
+typedef struct IMAGE_AUX_SYMBOL_TOKEN_DEF {
+ BYTE bAuxType;
+ BYTE bReserved;
+ DWORD SymbolTableIndex;
+ BYTE rgbReserved[12];
+} IMAGE_AUX_SYMBOL_TOKEN_DEF, UNALIGNED *PIMAGE_AUX_SYMBOL_TOKEN_DEF;
+
+typedef union _IMAGE_AUX_SYMBOL {
+ struct {
+ DWORD TagIndex;
+ union {
+ struct {
+ WORD Linenumber;
+ WORD Size;
+ } LnSz;
+ DWORD TotalSize;
+ } Misc;
+ union {
+ struct {
+ DWORD PointerToLinenumber;
+ DWORD PointerToNextFunction;
+ } Function;
+ struct {
+ WORD Dimension[4];
+ } Array;
+ } FcnAry;
+ WORD TvIndex;
+ } Sym;
+ struct {
+ BYTE Name[IMAGE_SIZEOF_SYMBOL];
+ } File;
+ struct {
+ DWORD Length;
+ WORD NumberOfRelocations;
+ WORD NumberOfLinenumbers;
+ DWORD CheckSum;
+ SHORT Number;
+ BYTE Selection;
+ BYTE bReserved;
+ SHORT HighNumber;
+ } Section;
+ IMAGE_AUX_SYMBOL_TOKEN_DEF TokenDef;
+ struct {
+ DWORD crc;
+ BYTE rgbReserved[14];
+ } CRC;
+} IMAGE_AUX_SYMBOL, *PIMAGE_AUX_SYMBOL;
+
+typedef struct _IMAGE_RELOCATION {
+ _ANONYMOUS_UNION union {
+ DWORD VirtualAddress;
+ DWORD RelocCount;
+ } DUMMYUNIONNAME;
+ DWORD SymbolTableIndex;
+ WORD Type;
+} IMAGE_RELOCATION, UNALIGNED *PIMAGE_RELOCATION;
+
+#include <poppack.h>
+
+#ifndef __IMAGE_COR20_HEADER_DEFINED__
+#define __IMAGE_COR20_HEADER_DEFINED__
+
+typedef enum ReplacesCorHdrNumericDefines {
+ COMIMAGE_FLAGS_ILONLY = 0x00000001,
+ COMIMAGE_FLAGS_32BITREQUIRED = 0x00000002,
+ COMIMAGE_FLAGS_IL_LIBRARY = 0x00000004,
+ COMIMAGE_FLAGS_STRONGNAMESIGNED = 0x00000008,
+ COMIMAGE_FLAGS_NATIVE_ENTRYPOINT = 0x00000010,
+ COMIMAGE_FLAGS_TRACKDEBUGDATA = 0x00010000,
+ COR_VERSION_MAJOR_V2 = 2,
+ COR_VERSION_MAJOR = COR_VERSION_MAJOR_V2,
+ COR_VERSION_MINOR = 0,
+ COR_DELETED_NAME_LENGTH = 8,
+ COR_VTABLEGAP_NAME_LENGTH = 8,
+ NATIVE_TYPE_MAX_CB = 1,
+ COR_ILMETHOD_SECT_SMALL_MAX_DATASIZE = 0xFF,
+ IMAGE_COR_MIH_METHODRVA = 0x01,
+ IMAGE_COR_MIH_EHRVA = 0x02,
+ IMAGE_COR_MIH_BASICBLOCK = 0x08,
+ COR_VTABLE_32BIT = 0x01,
+ COR_VTABLE_64BIT = 0x02,
+ COR_VTABLE_FROM_UNMANAGED = 0x04,
+ COR_VTABLE_FROM_UNMANAGED_RETAIN_APPDOMAIN = 0x08,
+ COR_VTABLE_CALL_MOST_DERIVED = 0x10,
+ IMAGE_COR_EATJ_THUNK_SIZE = 32,
+ MAX_CLASS_NAME = 1024,
+ MAX_PACKAGE_NAME = 1024
+} ReplacesCorHdrNumericDefines;
+
+typedef struct IMAGE_COR20_HEADER {
+ DWORD cb;
+ WORD MajorRuntimeVersion;
+ WORD MinorRuntimeVersion;
+ IMAGE_DATA_DIRECTORY MetaData;
+ DWORD Flags;
+ _ANONYMOUS_UNION union {
+ DWORD EntryPointToken;
+ DWORD EntryPointRVA;
+ } DUMMYUNIONNAME;
+ IMAGE_DATA_DIRECTORY Resources;
+ IMAGE_DATA_DIRECTORY StrongNameSignature;
+ IMAGE_DATA_DIRECTORY CodeManagerTable;
+ IMAGE_DATA_DIRECTORY VTableFixups;
+ IMAGE_DATA_DIRECTORY ExportAddressTableJumps;
+ IMAGE_DATA_DIRECTORY ManagedNativeHeader;
+} IMAGE_COR20_HEADER, *PIMAGE_COR20_HEADER;
+
+#endif /* __IMAGE_COR20_HEADER_DEFINED__ */
+
+typedef struct _IMAGE_COFF_SYMBOLS_HEADER {
+ DWORD NumberOfSymbols;
+ DWORD LvaToFirstSymbol;
+ DWORD NumberOfLinenumbers;
+ DWORD LvaToFirstLinenumber;
+ DWORD RvaToFirstByteOfCode;
+ DWORD RvaToLastByteOfCode;
+ DWORD RvaToFirstByteOfData;
+ DWORD RvaToLastByteOfData;
+} IMAGE_COFF_SYMBOLS_HEADER, *PIMAGE_COFF_SYMBOLS_HEADER;
+
+typedef struct _IMAGE_BASE_RELOCATION {
+ DWORD VirtualAddress;
+ DWORD SizeOfBlock;
+} IMAGE_BASE_RELOCATION, UNALIGNED *PIMAGE_BASE_RELOCATION;
+
+typedef struct _IMAGE_ARCHIVE_MEMBER_HEADER {
+ BYTE Name[16];
+ BYTE Date[12];
+ BYTE UserID[6];
+ BYTE GroupID[6];
+ BYTE Mode[8];
+ BYTE Size[10];
+ BYTE EndHeader[2];
+} IMAGE_ARCHIVE_MEMBER_HEADER, *PIMAGE_ARCHIVE_MEMBER_HEADER;
+
+typedef struct _IMAGE_EXPORT_DIRECTORY {
+ DWORD Characteristics;
+ DWORD TimeDateStamp;
+ WORD MajorVersion;
+ WORD MinorVersion;
+ DWORD Name;
+ DWORD Base;
+ DWORD NumberOfFunctions;
+ DWORD NumberOfNames;
+ DWORD AddressOfFunctions;
+ DWORD AddressOfNames;
+ DWORD AddressOfNameOrdinals;
+} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
+
+typedef struct _IMAGE_IMPORT_BY_NAME {
+ WORD Hint;
+ BYTE Name[1];
+} IMAGE_IMPORT_BY_NAME, *PIMAGE_IMPORT_BY_NAME;
+
+#include <pshpack8.h>
+typedef struct _IMAGE_THUNK_DATA64 {
+ union {
+ ULONGLONG ForwarderString;
+ ULONGLONG Function;
+ ULONGLONG Ordinal;
+ ULONGLONG AddressOfData;
+ } u1;
+} IMAGE_THUNK_DATA64, *PIMAGE_THUNK_DATA64;
+#include <poppack.h>
+
+typedef struct _IMAGE_THUNK_DATA32 {
+ union {
+ DWORD ForwarderString;
+ DWORD Function;
+ DWORD Ordinal;
+ DWORD AddressOfData;
+ } u1;
+} IMAGE_THUNK_DATA32, *PIMAGE_THUNK_DATA32;
+
+#define IMAGE_ORDINAL_FLAG64 0x8000000000000000ULL
+#define IMAGE_ORDINAL_FLAG32 0x80000000
+#define IMAGE_ORDINAL64(Ordinal) (Ordinal & 0xffff)
+#define IMAGE_ORDINAL32(Ordinal) (Ordinal & 0xffff)
+#define IMAGE_SNAP_BY_ORDINAL64(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG64)!=0)
+#define IMAGE_SNAP_BY_ORDINAL32(Ordinal) ((Ordinal & IMAGE_ORDINAL_FLAG32)!=0)
+
+typedef VOID
+(NTAPI *PIMAGE_TLS_CALLBACK)(PVOID DllHandle,DWORD Reason,PVOID Reserved);
+
+typedef struct _IMAGE_TLS_DIRECTORY64 {
+ ULONGLONG StartAddressOfRawData;
+ ULONGLONG EndAddressOfRawData;
+ ULONGLONG AddressOfIndex;
+ ULONGLONG AddressOfCallBacks;
+ DWORD SizeOfZeroFill;
+ DWORD Characteristics;
+} IMAGE_TLS_DIRECTORY64, *PIMAGE_TLS_DIRECTORY64;
+
+typedef struct _IMAGE_TLS_DIRECTORY32 {
+ DWORD StartAddressOfRawData;
+ DWORD EndAddressOfRawData;
+ DWORD AddressOfIndex;
+ DWORD AddressOfCallBacks;
+ DWORD SizeOfZeroFill;
+ DWORD Characteristics;
+} IMAGE_TLS_DIRECTORY32, *PIMAGE_TLS_DIRECTORY32;
+
+#ifdef _WIN64
+#define IMAGE_ORDINAL_FLAG IMAGE_ORDINAL_FLAG64
+#define IMAGE_ORDINAL(Ordinal) IMAGE_ORDINAL64(Ordinal)
+typedef IMAGE_THUNK_DATA64 IMAGE_THUNK_DATA;
+typedef PIMAGE_THUNK_DATA64 PIMAGE_THUNK_DATA;
+#define IMAGE_SNAP_BY_ORDINAL(Ordinal) IMAGE_SNAP_BY_ORDINAL64(Ordinal)
+typedef IMAGE_TLS_DIRECTORY64 IMAGE_TLS_DIRECTORY;
+typedef PIMAGE_TLS_DIRECTORY64 PIMAGE_TLS_DIRECTORY;
+#else
+#define IMAGE_ORDINAL_FLAG IMAGE_ORDINAL_FLAG32
+#define IMAGE_ORDINAL(Ordinal) IMAGE_ORDINAL32(Ordinal)
+typedef IMAGE_THUNK_DATA32 IMAGE_THUNK_DATA;
+typedef PIMAGE_THUNK_DATA32 PIMAGE_THUNK_DATA;
+#define IMAGE_SNAP_BY_ORDINAL(Ordinal) IMAGE_SNAP_BY_ORDINAL32(Ordinal)
+typedef IMAGE_TLS_DIRECTORY32 IMAGE_TLS_DIRECTORY;
+typedef PIMAGE_TLS_DIRECTORY32 PIMAGE_TLS_DIRECTORY;
+#endif
+
+typedef struct _IMAGE_IMPORT_DESCRIPTOR {
+ _ANONYMOUS_UNION union {
+ DWORD Characteristics;
+ DWORD OriginalFirstThunk;
+ } DUMMYUNIONNAME;
+ DWORD TimeDateStamp;
+ DWORD ForwarderChain;
+ DWORD Name;
+ DWORD FirstThunk;
+} IMAGE_IMPORT_DESCRIPTOR, UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;
+
+typedef struct _IMAGE_BOUND_IMPORT_DESCRIPTOR {
+ DWORD TimeDateStamp;
+ WORD OffsetModuleName;
+ WORD NumberOfModuleForwarderRefs;
+} IMAGE_BOUND_IMPORT_DESCRIPTOR, *PIMAGE_BOUND_IMPORT_DESCRIPTOR;
+
+typedef struct _IMAGE_BOUND_FORWARDER_REF {
+ DWORD TimeDateStamp;
+ WORD OffsetModuleName;
+ WORD Reserved;
+} IMAGE_BOUND_FORWARDER_REF, *PIMAGE_BOUND_FORWARDER_REF;
+
+typedef struct _IMAGE_RESOURCE_DIRECTORY {
+ DWORD Characteristics;
+ DWORD TimeDateStamp;
+ WORD MajorVersion;
+ WORD MinorVersion;
+ WORD NumberOfNamedEntries;
+ WORD NumberOfIdEntries;
+} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;
+
+typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {
+ _ANONYMOUS_UNION union {
+ _ANONYMOUS_STRUCT struct {
+ DWORD NameOffset:31;
+ DWORD NameIsString:1;
+ } DUMMYSTRUCTNAME1;
+ DWORD Name;
+ WORD Id;
+ } DUMMYUNIONNAME1;
+ _ANONYMOUS_UNION union {
+ DWORD OffsetToData;
+ _ANONYMOUS_STRUCT struct {
+ DWORD OffsetToDirectory:31;
+ DWORD DataIsDirectory:1;
+ } DUMMYSTRUCTNAME3;
+ } DUMMYUNIONNAME2;
+} IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;
+
+typedef struct _IMAGE_RESOURCE_DIRECTORY_STRING {
+ WORD Length;
+ CHAR NameString[1];
+} IMAGE_RESOURCE_DIRECTORY_STRING, *PIMAGE_RESOURCE_DIRECTORY_STRING;
+
+typedef struct _IMAGE_RESOURCE_DIR_STRING_U {
+ WORD Length;
+ WCHAR NameString[1];
+} IMAGE_RESOURCE_DIR_STRING_U, *PIMAGE_RESOURCE_DIR_STRING_U;
+
+typedef struct _IMAGE_RESOURCE_DATA_ENTRY {
+ DWORD OffsetToData;
+ DWORD Size;
+ DWORD CodePage;
+ DWORD Reserved;
+} IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY;
+
+typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY32 {
+ DWORD Size;
+ DWORD TimeDateStamp;
+ WORD MajorVersion;
+ WORD MinorVersion;
+ DWORD GlobalFlagsClear;
+ DWORD GlobalFlagsSet;
+ DWORD CriticalSectionDefaultTimeout;
+ DWORD DeCommitFreeBlockThreshold;
+ DWORD DeCommitTotalFreeThreshold;
+ DWORD LockPrefixTable;
+ DWORD MaximumAllocationSize;
+ DWORD VirtualMemoryThreshold;
+ DWORD ProcessHeapFlags;
+ DWORD ProcessAffinityMask;
+ WORD CSDVersion;
+ WORD Reserved1;
+ DWORD EditList;
+ DWORD SecurityCookie;
+ DWORD SEHandlerTable;
+ DWORD SEHandlerCount;
+} IMAGE_LOAD_CONFIG_DIRECTORY32, *PIMAGE_LOAD_CONFIG_DIRECTORY32;
+
+typedef struct _IMAGE_LOAD_CONFIG_DIRECTORY64 {
+ DWORD Size;
+ DWORD TimeDateStamp;
+ WORD MajorVersion;
+ WORD MinorVersion;
+ DWORD GlobalFlagsClear;
+ DWORD GlobalFlagsSet;
+ DWORD CriticalSectionDefaultTimeout;
+ ULONGLONG DeCommitFreeBlockThreshold;
+ ULONGLONG DeCommitTotalFreeThreshold;
+ ULONGLONG LockPrefixTable;
+ ULONGLONG MaximumAllocationSize;
+ ULONGLONG VirtualMemoryThreshold;
+ ULONGLONG ProcessAffinityMask;
+ DWORD ProcessHeapFlags;
+ WORD CSDVersion;
+ WORD Reserved1;
+ ULONGLONG EditList;
+ ULONGLONG SecurityCookie;
+ ULONGLONG SEHandlerTable;
+ ULONGLONG SEHandlerCount;
+} IMAGE_LOAD_CONFIG_DIRECTORY64, *PIMAGE_LOAD_CONFIG_DIRECTORY64;
+
+#ifdef _WIN64
+typedef IMAGE_LOAD_CONFIG_DIRECTORY64 IMAGE_LOAD_CONFIG_DIRECTORY;
+typedef PIMAGE_LOAD_CONFIG_DIRECTORY64 PIMAGE_LOAD_CONFIG_DIRECTORY;
+#else
+typedef IMAGE_LOAD_CONFIG_DIRECTORY32 IMAGE_LOAD_CONFIG_DIRECTORY;
+typedef PIMAGE_LOAD_CONFIG_DIRECTORY32 PIMAGE_LOAD_CONFIG_DIRECTORY;
+#endif
+
+typedef struct _IMAGE_RUNTIME_FUNCTION_ENTRY {
+ DWORD BeginAddress;
+ DWORD EndAddress;
+ DWORD UnwindInfoAddress;
+} IMAGE_RUNTIME_FUNCTION_ENTRY, *PIMAGE_RUNTIME_FUNCTION_ENTRY;
+
+typedef struct _IMAGE_DEBUG_DIRECTORY {
+ DWORD Characteristics;
+ DWORD TimeDateStamp;
+ WORD MajorVersion;
+ WORD MinorVersion;
+ DWORD Type;
+ DWORD SizeOfData;
+ DWORD AddressOfRawData;
+ DWORD PointerToRawData;
+} IMAGE_DEBUG_DIRECTORY, *PIMAGE_DEBUG_DIRECTORY;
+
+typedef struct _FPO_DATA {
+ DWORD ulOffStart;
+ DWORD cbProcSize;
+ DWORD cdwLocals;
+ WORD cdwParams;
+ WORD cbProlog:8;
+ WORD cbRegs:3;
+ WORD fHasSEH:1;
+ WORD fUseBP:1;
+ WORD reserved:1;
+ WORD cbFrame:2;
+} FPO_DATA, *PFPO_DATA;
+
+typedef struct _IMAGE_DEBUG_MISC {
+ DWORD DataType;
+ DWORD Length;
+ BOOLEAN Unicode;
+ BYTE Reserved[3];
+ BYTE Data[1];
+} IMAGE_DEBUG_MISC, *PIMAGE_DEBUG_MISC;
+
+typedef struct _IMAGE_FUNCTION_ENTRY {
+ DWORD StartingAddress;
+ DWORD EndingAddress;
+ DWORD EndOfPrologue;
+} IMAGE_FUNCTION_ENTRY, *PIMAGE_FUNCTION_ENTRY;
+
+typedef struct _IMAGE_SEPARATE_DEBUG_HEADER {
+ WORD Signature;
+ WORD Flags;
+ WORD Machine;
+ WORD Characteristics;
+ DWORD TimeDateStamp;
+ DWORD CheckSum;
+ DWORD ImageBase;
+ DWORD SizeOfImage;
+ DWORD NumberOfSections;
+ DWORD ExportedNamesSize;
+ DWORD DebugDirectorySize;
+ DWORD SectionAlignment;
+ DWORD Reserved[2];
+} IMAGE_SEPARATE_DEBUG_HEADER, *PIMAGE_SEPARATE_DEBUG_HEADER;
+
+typedef enum _CM_SERVICE_NODE_TYPE {
+ DriverType = SERVICE_KERNEL_DRIVER,
+ FileSystemType = SERVICE_FILE_SYSTEM_DRIVER,
+ Win32ServiceOwnProcess = SERVICE_WIN32_OWN_PROCESS,
+ Win32ServiceShareProcess = SERVICE_WIN32_SHARE_PROCESS,
+ AdapterType = SERVICE_ADAPTER,
+ RecognizerType = SERVICE_RECOGNIZER_DRIVER
+} SERVICE_NODE_TYPE;
+
+typedef enum _CM_SERVICE_LOAD_TYPE {
+ BootLoad = SERVICE_BOOT_START,
+ SystemLoad = SERVICE_SYSTEM_START,
+ AutoLoad = SERVICE_AUTO_START,
+ DemandLoad = SERVICE_DEMAND_START,
+ DisableLoad = SERVICE_DISABLED
+} SERVICE_LOAD_TYPE;
+
+typedef enum _CM_ERROR_CONTROL_TYPE {
+ IgnoreError = SERVICE_ERROR_IGNORE,
+ NormalError = SERVICE_ERROR_NORMAL,
+ SevereError = SERVICE_ERROR_SEVERE,
+ CriticalError = SERVICE_ERROR_CRITICAL
+} SERVICE_ERROR_TYPE;
+
+typedef struct _NT_TIB {
+ struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList;
+ PVOID StackBase;
+ PVOID StackLimit;
+ PVOID SubSystemTib;
+ _ANONYMOUS_UNION union {
+ PVOID FiberData;
+ DWORD Version;
+ } DUMMYUNIONNAME;
+ PVOID ArbitraryUserPointer;
+ struct _NT_TIB *Self;
+} NT_TIB,*PNT_TIB;
+
+typedef struct _NT_TIB32 {
+ DWORD ExceptionList;
+ DWORD StackBase;
+ DWORD StackLimit;
+ DWORD SubSystemTib;
+ _ANONYMOUS_UNION union {
+ DWORD FiberData;
+ DWORD Version;
+ } DUMMYUNIONNAME;
+ DWORD ArbitraryUserPointer;
+ DWORD Self;
+} NT_TIB32,*PNT_TIB32;
+
+typedef struct _NT_TIB64 {
+ DWORD64 ExceptionList;
+ DWORD64 StackBase;
+ DWORD64 StackLimit;
+ DWORD64 SubSystemTib;
+ _ANONYMOUS_UNION union {
+ DWORD64 FiberData;
+ DWORD Version;
+ } DUMMYUNIONNAME;
+ DWORD64 ArbitraryUserPointer;
+ DWORD64 Self;
+} NT_TIB64,*PNT_TIB64;
+
+typedef struct _REPARSE_GUID_DATA_BUFFER {
+ DWORD ReparseTag;
+ WORD ReparseDataLength;
+ WORD Reserved;
+ GUID ReparseGuid;
+ struct {
+ BYTE DataBuffer[1];
+ } GenericReparseBuffer;
+} REPARSE_GUID_DATA_BUFFER, *PREPARSE_GUID_DATA_BUFFER;
+
+typedef struct _REPARSE_POINT_INFORMATION {
+ WORD ReparseDataLength;
+ WORD UnparsedNameLength;
+} REPARSE_POINT_INFORMATION, *PREPARSE_POINT_INFORMATION;
+
+typedef union _FILE_SEGMENT_ELEMENT {
+ PVOID64 Buffer;
+ ULONGLONG Alignment;
+} FILE_SEGMENT_ELEMENT, *PFILE_SEGMENT_ELEMENT;
+
+/* JOBOBJECT_BASIC_LIMIT_INFORMATION.LimitFlags constants */
+#define JOB_OBJECT_LIMIT_WORKINGSET 0x0001
+#define JOB_OBJECT_LIMIT_PROCESS_TIME 0x0002
+#define JOB_OBJECT_LIMIT_JOB_TIME 0x0004
+#define JOB_OBJECT_LIMIT_ACTIVE_PROCESS 0x0008
+#define JOB_OBJECT_LIMIT_AFFINITY 0x0010
+#define JOB_OBJECT_LIMIT_PRIORITY_CLASS 0x0020
+#define JOB_OBJECT_LIMIT_PRESERVE_JOB_TIME 0x0040
+#define JOB_OBJECT_LIMIT_SCHEDULING_CLASS 0x0080
+#define JOB_OBJECT_LIMIT_PROCESS_MEMORY 0x0100
+#define JOB_OBJECT_LIMIT_JOB_MEMORY 0x0200
+#define JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION 0x0400
+#define JOB_OBJECT_BREAKAWAY_OK 0x0800
+#define JOB_OBJECT_SILENT_BREAKAWAY 0x1000
+
+/* JOBOBJECT_BASIC_UI_RESTRICTIONS.UIRestrictionsClass constants */
+#define JOB_OBJECT_UILIMIT_HANDLES 0x0001
+#define JOB_OBJECT_UILIMIT_READCLIPBOARD 0x0002
+#define JOB_OBJECT_UILIMIT_WRITECLIPBOARD 0x0004
+#define JOB_OBJECT_UILIMIT_SYSTEMPARAMETERS 0x0008
+#define JOB_OBJECT_UILIMIT_DISPLAYSETTINGS 0x0010
+#define JOB_OBJECT_UILIMIT_GLOBALATOMS 0x0020
+#define JOB_OBJECT_UILIMIT_DESKTOP 0x0040
+#define JOB_OBJECT_UILIMIT_EXITWINDOWS 0x0080
+
+/* JOBOBJECT_SECURITY_LIMIT_INFORMATION.SecurityLimitFlags constants */
+#define JOB_OBJECT_SECURITY_NO_ADMIN 0x0001
+#define JOB_OBJECT_SECURITY_RESTRICTED_TOKEN 0x0002
+#define JOB_OBJECT_SECURITY_ONLY_TOKEN 0x0004
+#define JOB_OBJECT_SECURITY_FILTER_TOKENS 0x0008
+
+/* JOBOBJECT_END_OF_JOB_TIME_INFORMATION.EndOfJobTimeAction constants */
+#define JOB_OBJECT_TERMINATE_AT_END_OF_JOB 0
+#define JOB_OBJECT_POST_AT_END_OF_JOB 1
+
+#define JOB_OBJECT_MSG_END_OF_JOB_TIME 1
+#define JOB_OBJECT_MSG_END_OF_PROCESS_TIME 2
+#define JOB_OBJECT_MSG_ACTIVE_PROCESS_LIMIT 3
+#define JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO 4
+#define JOB_OBJECT_MSG_NEW_PROCESS 6
+#define JOB_OBJECT_MSG_EXIT_PROCESS 7
+#define JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS 8
+#define JOB_OBJECT_MSG_PROCESS_MEMORY_LIMIT 9
+#define JOB_OBJECT_MSG_JOB_MEMORY_LIMIT 10
+
+#define JOB_OBJECT_ASSIGN_PROCESS 1
+#define JOB_OBJECT_SET_ATTRIBUTES 2
+#define JOB_OBJECT_QUERY 4
+#define JOB_OBJECT_TERMINATE 8
+#define JOB_OBJECT_SET_SECURITY_ATTRIBUTES 16
+#define JOB_OBJECT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|31)
+
+typedef enum _JOBOBJECTINFOCLASS {
+ JobObjectBasicAccountingInformation = 1,
+ JobObjectBasicLimitInformation,
+ JobObjectBasicProcessIdList,
+ JobObjectBasicUIRestrictions,
+ JobObjectSecurityLimitInformation,
+ JobObjectEndOfJobTimeInformation,
+ JobObjectAssociateCompletionPortInformation,
+ JobObjectBasicAndIoAccountingInformation,
+ JobObjectExtendedLimitInformation,
+ JobObjectJobSetInformation,
+ JobObjectGroupInformation,
+ MaxJobObjectInfoClass
+} JOBOBJECTINFOCLASS;
+
+typedef struct _JOB_SET_ARRAY {
+ HANDLE JobHandle;
+ DWORD MemberLevel;
+ DWORD Flags;
+} JOB_SET_ARRAY, *PJOB_SET_ARRAY;
+
+typedef struct _JOBOBJECT_BASIC_ACCOUNTING_INFORMATION {
+ LARGE_INTEGER TotalUserTime;
+ LARGE_INTEGER TotalKernelTime;
+ LARGE_INTEGER ThisPeriodTotalUserTime;
+ LARGE_INTEGER ThisPeriodTotalKernelTime;
+ DWORD TotalPageFaultCount;
+ DWORD TotalProcesses;
+ DWORD ActiveProcesses;
+ DWORD TotalTerminatedProcesses;
+} JOBOBJECT_BASIC_ACCOUNTING_INFORMATION,*PJOBOBJECT_BASIC_ACCOUNTING_INFORMATION;
+
+typedef struct _JOBOBJECT_BASIC_LIMIT_INFORMATION {
+ LARGE_INTEGER PerProcessUserTimeLimit;
+ LARGE_INTEGER PerJobUserTimeLimit;
+ DWORD LimitFlags;
+ SIZE_T MinimumWorkingSetSize;
+ SIZE_T MaximumWorkingSetSize;
+ DWORD ActiveProcessLimit;
+ ULONG_PTR Affinity;
+ DWORD PriorityClass;
+ DWORD SchedulingClass;
+} JOBOBJECT_BASIC_LIMIT_INFORMATION,*PJOBOBJECT_BASIC_LIMIT_INFORMATION;
+
+typedef struct _JOBOBJECT_BASIC_PROCESS_ID_LIST {
+ DWORD NumberOfAssignedProcesses;
+ DWORD NumberOfProcessIdsInList;
+ ULONG_PTR ProcessIdList[1];
+} JOBOBJECT_BASIC_PROCESS_ID_LIST, *PJOBOBJECT_BASIC_PROCESS_ID_LIST;
+
+typedef struct _JOBOBJECT_BASIC_UI_RESTRICTIONS {
+ DWORD UIRestrictionsClass;
+} JOBOBJECT_BASIC_UI_RESTRICTIONS,*PJOBOBJECT_BASIC_UI_RESTRICTIONS;
+
+typedef struct _JOBOBJECT_SECURITY_LIMIT_INFORMATION {
+ DWORD SecurityLimitFlags;
+ HANDLE JobToken;
+ PTOKEN_GROUPS SidsToDisable;
+ PTOKEN_PRIVILEGES PrivilegesToDelete;
+ PTOKEN_GROUPS RestrictedSids;
+} JOBOBJECT_SECURITY_LIMIT_INFORMATION,*PJOBOBJECT_SECURITY_LIMIT_INFORMATION;
+
+typedef struct _JOBOBJECT_END_OF_JOB_TIME_INFORMATION {
+ DWORD EndOfJobTimeAction;
+} JOBOBJECT_END_OF_JOB_TIME_INFORMATION,*PJOBOBJECT_END_OF_JOB_TIME_INFORMATION;
+
+typedef struct _JOBOBJECT_ASSOCIATE_COMPLETION_PORT {
+ PVOID CompletionKey;
+ HANDLE CompletionPort;
+} JOBOBJECT_ASSOCIATE_COMPLETION_PORT,*PJOBOBJECT_ASSOCIATE_COMPLETION_PORT;
+
+typedef struct _JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION {
+ JOBOBJECT_BASIC_ACCOUNTING_INFORMATION BasicInfo;
+ IO_COUNTERS IoInfo;
+} JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION,*PJOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION;
+
+typedef struct _JOBOBJECT_EXTENDED_LIMIT_INFORMATION {
+ JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation;
+ IO_COUNTERS IoInfo;
+ SIZE_T ProcessMemoryLimit;
+ SIZE_T JobMemoryLimit;
+ SIZE_T PeakProcessMemoryUsed;
+ SIZE_T PeakJobMemoryUsed;
+} JOBOBJECT_EXTENDED_LIMIT_INFORMATION,*PJOBOBJECT_EXTENDED_LIMIT_INFORMATION;
+
+typedef struct _JOBOBJECT_JOBSET_INFORMATION {
+ DWORD MemberLevel;
+} JOBOBJECT_JOBSET_INFORMATION,*PJOBOBJECT_JOBSET_INFORMATION;
+
+/* Fixme: Making these defines conditional on WINVER will break ddk includes */
+#if 1 /* (WINVER >= 0x0500) */
+
+#define ES_SYSTEM_REQUIRED 0x00000001
+#define ES_DISPLAY_REQUIRED 0x00000002
+#define ES_USER_PRESENT 0x00000004
+#define ES_CONTINUOUS 0x80000000
+
+typedef enum _LATENCY_TIME {
+ LT_DONT_CARE,
+ LT_LOWEST_LATENCY
+} LATENCY_TIME, *PLATENCY_TIME;
+
+typedef enum _SYSTEM_POWER_STATE {
+ PowerSystemUnspecified = 0,
+ PowerSystemWorking,
+ PowerSystemSleeping1,
+ PowerSystemSleeping2,
+ PowerSystemSleeping3,
+ PowerSystemHibernate,
+ PowerSystemShutdown,
+ PowerSystemMaximum
+} SYSTEM_POWER_STATE, *PSYSTEM_POWER_STATE;
+
+#define POWER_SYSTEM_MAXIMUM PowerSystemMaximum
+
+typedef enum {
+ PowerActionNone = 0,
+ PowerActionReserved,
+ PowerActionSleep,
+ PowerActionHibernate,
+ PowerActionShutdown,
+ PowerActionShutdownReset,
+ PowerActionShutdownOff,
+ PowerActionWarmEject
+} POWER_ACTION, *PPOWER_ACTION;
+
+typedef enum _DEVICE_POWER_STATE {
+ PowerDeviceUnspecified = 0,
+ PowerDeviceD0,
+ PowerDeviceD1,
+ PowerDeviceD2,
+ PowerDeviceD3,
+ PowerDeviceMaximum
+} DEVICE_POWER_STATE, *PDEVICE_POWER_STATE;
+
+#if (NTDDI_VERSION >= NTDDI_WINXP) || !defined(_BATCLASS_)
+typedef struct {
+ DWORD Granularity;
+ DWORD Capacity;
+} BATTERY_REPORTING_SCALE, *PBATTERY_REPORTING_SCALE;
+#endif
+
+typedef struct _POWER_ACTION_POLICY {
+ POWER_ACTION Action;
+ DWORD Flags;
+ DWORD EventCode;
+} POWER_ACTION_POLICY, *PPOWER_ACTION_POLICY;
+
+/* POWER_ACTION_POLICY.Flags constants */
+#define POWER_ACTION_QUERY_ALLOWED 0x00000001
+#define POWER_ACTION_UI_ALLOWED 0x00000002
+#define POWER_ACTION_OVERRIDE_APPS 0x00000004
+#define POWER_ACTION_LIGHTEST_FIRST 0x10000000
+#define POWER_ACTION_LOCK_CONSOLE 0x20000000
+#define POWER_ACTION_DISABLE_WAKES 0x40000000
+#define POWER_ACTION_CRITICAL 0x80000000
+
+/* POWER_ACTION_POLICY.EventCode constants */
+#define POWER_LEVEL_USER_NOTIFY_TEXT 0x00000001
+#define POWER_LEVEL_USER_NOTIFY_SOUND 0x00000002
+#define POWER_LEVEL_USER_NOTIFY_EXEC 0x00000004
+#define POWER_USER_NOTIFY_BUTTON 0x00000008
+#define POWER_USER_NOTIFY_SHUTDOWN 0x00000010
+#define POWER_FORCE_TRIGGER_RESET 0x80000000
+
+#define DISCHARGE_POLICY_CRITICAL 0
+#define DISCHARGE_POLICY_LOW 1
+#define NUM_DISCHARGE_POLICIES 4
+
+#define PO_THROTTLE_NONE 0
+#define PO_THROTTLE_CONSTANT 1
+#define PO_THROTTLE_DEGRADE 2
+#define PO_THROTTLE_ADAPTIVE 3
+#define PO_THROTTLE_MAXIMUM 4
+
+typedef struct _SYSTEM_POWER_LEVEL {
+ BOOLEAN Enable;
+ BYTE Spare[3];
+ DWORD BatteryLevel;
+ POWER_ACTION_POLICY PowerPolicy;
+ SYSTEM_POWER_STATE MinSystemState;
+} SYSTEM_POWER_LEVEL, *PSYSTEM_POWER_LEVEL;
+
+typedef struct _SYSTEM_POWER_POLICY {
+ DWORD Revision;
+ POWER_ACTION_POLICY PowerButton;
+ POWER_ACTION_POLICY SleepButton;
+ POWER_ACTION_POLICY LidClose;
+ SYSTEM_POWER_STATE LidOpenWake;
+ DWORD Reserved;
+ POWER_ACTION_POLICY Idle;
+ DWORD IdleTimeout;
+ BYTE IdleSensitivity;
+ BYTE DynamicThrottle;
+ BYTE Spare2[2];
+ SYSTEM_POWER_STATE MinSleep;
+ SYSTEM_POWER_STATE MaxSleep;
+ SYSTEM_POWER_STATE ReducedLatencySleep;
+ DWORD WinLogonFlags;
+ DWORD Spare3;
+ DWORD DozeS4Timeout;
+ DWORD BroadcastCapacityResolution;
+ SYSTEM_POWER_LEVEL DischargePolicy[NUM_DISCHARGE_POLICIES];
+ DWORD VideoTimeout;
+ BOOLEAN VideoDimDisplay;
+ DWORD VideoReserved[3];
+ DWORD SpindownTimeout;
+ BOOLEAN OptimizeForPower;
+ BYTE FanThrottleTolerance;
+ BYTE ForcedThrottle;
+ BYTE MinThrottle;
+ POWER_ACTION_POLICY OverThrottled;
+} SYSTEM_POWER_POLICY, *PSYSTEM_POWER_POLICY;
+
+typedef struct _SYSTEM_POWER_CAPABILITIES {
+ BOOLEAN PowerButtonPresent;
+ BOOLEAN SleepButtonPresent;
+ BOOLEAN LidPresent;
+ BOOLEAN SystemS1;
+ BOOLEAN SystemS2;
+ BOOLEAN SystemS3;
+ BOOLEAN SystemS4;
+ BOOLEAN SystemS5;
+ BOOLEAN HiberFilePresent;
+ BOOLEAN FullWake;
+ BOOLEAN VideoDimPresent;
+ BOOLEAN ApmPresent;
+ BOOLEAN UpsPresent;
+ BOOLEAN ThermalControl;
+ BOOLEAN ProcessorThrottle;
+ BYTE ProcessorMinThrottle;
+#if (NTDDI_VERSION < NTDDI_WINXP)
+ BYTE ProcessorThrottleScale;
+ BYTE spare2[4];
+#else
+ BYTE ProcessorMaxThrottle;
+ BOOLEAN FastSystemS4;
+ BYTE spare2[3];
+#endif /* (NTDDI_VERSION < NTDDI_WINXP) */
+ BOOLEAN DiskSpinDown;
+ BYTE spare3[8];
+ BOOLEAN SystemBatteriesPresent;
+ BOOLEAN BatteriesAreShortTerm;
+ BATTERY_REPORTING_SCALE BatteryScale[3];
+ SYSTEM_POWER_STATE AcOnLineWake;
+ SYSTEM_POWER_STATE SoftLidWake;
+ SYSTEM_POWER_STATE RtcWake;
+ SYSTEM_POWER_STATE MinDeviceWakeState;
+ SYSTEM_POWER_STATE DefaultLowLatencyWake;
+} SYSTEM_POWER_CAPABILITIES, *PSYSTEM_POWER_CAPABILITIES;
+
+typedef struct _SYSTEM_BATTERY_STATE {
+ BOOLEAN AcOnLine;
+ BOOLEAN BatteryPresent;
+ BOOLEAN Charging;
+ BOOLEAN Discharging;
+ BOOLEAN Spare1[4];
+ DWORD MaxCapacity;
+ DWORD RemainingCapacity;
+ DWORD Rate;
+ DWORD EstimatedTime;
+ DWORD DefaultAlert1;
+ DWORD DefaultAlert2;
+} SYSTEM_BATTERY_STATE, *PSYSTEM_BATTERY_STATE;
+
+typedef struct _PROCESSOR_POWER_INFORMATION {
+ ULONG Number;
+ ULONG MaxMhz;
+ ULONG CurrentMhz;
+ ULONG MhzLimit;
+ ULONG MaxIdleState;
+ ULONG CurrentIdleState;
+} PROCESSOR_POWER_INFORMATION, *PPROCESSOR_POWER_INFORMATION;
+
+typedef DWORD EXECUTION_STATE;
+
+typedef enum _POWER_INFORMATION_LEVEL {
+ SystemPowerPolicyAc,
+ SystemPowerPolicyDc,
+ VerifySystemPolicyAc,
+ VerifySystemPolicyDc,
+ SystemPowerCapabilities,
+ SystemBatteryState,
+ SystemPowerStateHandler,
+ ProcessorStateHandler,
+ SystemPowerPolicyCurrent,
+ AdministratorPowerPolicy,
+ SystemReserveHiberFile,
+ ProcessorInformation,
+ SystemPowerInformation,
+ ProcessorStateHandler2,
+ LastWakeTime,
+ LastSleepTime,
+ SystemExecutionState,
+ SystemPowerStateNotifyHandler,
+ ProcessorPowerPolicyAc,
+ ProcessorPowerPolicyDc,
+ VerifyProcessorPowerPolicyAc,
+ VerifyProcessorPowerPolicyDc,
+ ProcessorPowerPolicyCurrent,
+ SystemPowerStateLogging,
+ SystemPowerLoggingEntry,
+ SetPowerSettingValue,
+ NotifyUserPowerSetting,
+ PowerInformationLevelUnused0,
+ PowerInformationLevelUnused1,
+ SystemVideoState,
+ TraceApplicationPowerMessage,
+ TraceApplicationPowerMessageEnd,
+ ProcessorPerfStates,
+ ProcessorIdleStates,
+ ProcessorCap,
+ SystemWakeSource,
+ SystemHiberFileInformation,
+ TraceServicePowerMessage,
+ ProcessorLoad,
+ PowerShutdownNotification,
+ MonitorCapabilities,
+ SessionPowerInit,
+ SessionDisplayState,
+ PowerRequestCreate,
+ PowerRequestAction,
+ GetPowerRequestList,
+ ProcessorInformationEx,
+ NotifyUserModeLegacyPowerEvent,
+ GroupPark,
+ ProcessorIdleDomains,
+ WakeTimerList,
+ SystemHiberFileSize,
+ PowerInformationLevelMaximum
+} POWER_INFORMATION_LEVEL;
+
+#if 1 /* (WIN32_WINNT >= 0x0500) */
+typedef struct _SYSTEM_POWER_INFORMATION {
+ ULONG MaxIdlenessAllowed;
+ ULONG Idleness;
+ ULONG TimeRemaining;
+ UCHAR CoolingMode;
+} SYSTEM_POWER_INFORMATION,*PSYSTEM_POWER_INFORMATION;
+#endif
+
+#if (_WIN32_WINNT >= 0x0500)
+#define _AUDIT_EVENT_TYPE_HACK 1
+typedef enum _AUDIT_EVENT_TYPE {
+ AuditEventObjectAccess,
+ AuditEventDirectoryServiceAccess
+} AUDIT_EVENT_TYPE, *PAUDIT_EVENT_TYPE;
+#endif
+
+#if (_WIN32_WINNT >= 0x0501)
+
+typedef enum _ACTIVATION_CONTEXT_INFO_CLASS {
+ ActivationContextBasicInformation = 1,
+ ActivationContextDetailedInformation = 2,
+ AssemblyDetailedInformationInActivationContext = 3,
+ FileInformationInAssemblyOfAssemblyInActivationContext = 4,
+ RunlevelInformationInActivationContext = 5,
+ CompatibilityInformationInActivationContext = 6,
+ ActivationContextManifestResourceName = 7,
+ MaxActivationContextInfoClass,
+/* For compatibility with the old names */
+ AssemblyDetailedInformationInActivationContxt = 3,
+ FileInformationInAssemblyOfAssemblyInActivationContxt = 4
+} ACTIVATION_CONTEXT_INFO_CLASS;
+
+typedef struct _ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION {
+ DWORD ulFlags;
+ DWORD ulEncodedAssemblyIdentityLength;
+ DWORD ulManifestPathType;
+ DWORD ulManifestPathLength;
+ LARGE_INTEGER liManifestLastWriteTime;
+ DWORD ulPolicyPathType;
+ DWORD ulPolicyPathLength;
+ LARGE_INTEGER liPolicyLastWriteTime;
+ DWORD ulMetadataSatelliteRosterIndex;
+ DWORD ulManifestVersionMajor;
+ DWORD ulManifestVersionMinor;
+ DWORD ulPolicyVersionMajor;
+ DWORD ulPolicyVersionMinor;
+ DWORD ulAssemblyDirectoryNameLength;
+ PCWSTR lpAssemblyEncodedAssemblyIdentity;
+ PCWSTR lpAssemblyManifestPath;
+ PCWSTR lpAssemblyPolicyPath;
+ PCWSTR lpAssemblyDirectoryName;
+} ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION, *PACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION;
+typedef const ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION *PCACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION;
+
+typedef struct _ACTIVATION_CONTEXT_DETAILED_INFORMATION {
+ DWORD dwFlags;
+ DWORD ulFormatVersion;
+ DWORD ulAssemblyCount;
+ DWORD ulRootManifestPathType;
+ DWORD ulRootManifestPathChars;
+ DWORD ulRootConfigurationPathType;
+ DWORD ulRootConfigurationPathChars;
+ DWORD ulAppDirPathType;
+ DWORD ulAppDirPathChars;
+ PCWSTR lpRootManifestPath;
+ PCWSTR lpRootConfigurationPath;
+ PCWSTR lpAppDirPath;
+} ACTIVATION_CONTEXT_DETAILED_INFORMATION, *PACTIVATION_CONTEXT_DETAILED_INFORMATION;
+typedef const ACTIVATION_CONTEXT_DETAILED_INFORMATION *PCACTIVATION_CONTEXT_DETAILED_INFORMATION;
+
+typedef struct _ACTIVATION_CONTEXT_QUERY_INDEX {
+ DWORD ulAssemblyIndex;
+ DWORD ulFileIndexInAssembly;
+} ACTIVATION_CONTEXT_QUERY_INDEX,*PACTIVATION_CONTEXT_QUERY_INDEX;
+typedef const ACTIVATION_CONTEXT_QUERY_INDEX *PCACTIVATION_CONTEXT_QUERY_INDEX;
+
+typedef struct _ASSEMBLY_FILE_DETAILED_INFORMATION {
+ DWORD ulFlags;
+ DWORD ulFilenameLength;
+ DWORD ulPathLength;
+ PCWSTR lpFileName;
+ PCWSTR lpFilePath;
+} ASSEMBLY_FILE_DETAILED_INFORMATION,*PASSEMBLY_FILE_DETAILED_INFORMATION;
+typedef const ASSEMBLY_FILE_DETAILED_INFORMATION *PCASSEMBLY_FILE_DETAILED_INFORMATION;
+
+#define ACTIVATION_CONTEXT_PATH_TYPE_NONE 1
+#define ACTIVATION_CONTEXT_PATH_TYPE_WIN32_FILE 2
+#define ACTIVATION_CONTEXT_PATH_TYPE_URL 3
+#define ACTIVATION_CONTEXT_PATH_TYPE_ASSEMBLYREF 4
+
+#define ACTIVATION_CONTEXT_SECTION_ASSEMBLY_INFORMATION 1
+#define ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION 2
+#define ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION 3
+#define ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION 4
+#define ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION 5
+#define ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION 6
+#define ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION 7
+#define ACTIVATION_CONTEXT_SECTION_GLOBAL_OBJECT_RENAME_TABLE 8
+#define ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES 9
+
+#endif /* (WIN32_WINNT >= 0x0501) */
+
+typedef struct _PROCESSOR_POWER_POLICY_INFO {
+ DWORD TimeCheck;
+ DWORD DemoteLimit;
+ DWORD PromoteLimit;
+ BYTE DemotePercent;
+ BYTE PromotePercent;
+ BYTE Spare[2];
+ DWORD AllowDemotion:1;
+ DWORD AllowPromotion:1;
+ DWORD Reserved:30;
+} PROCESSOR_POWER_POLICY_INFO, *PPROCESSOR_POWER_POLICY_INFO;
+
+typedef struct _PROCESSOR_POWER_POLICY {
+ DWORD Revision;
+ BYTE DynamicThrottle;
+ BYTE Spare[3];
+ DWORD DisableCStates:1;
+ DWORD Reserved:31;
+ DWORD PolicyCount;
+ PROCESSOR_POWER_POLICY_INFO Policy[3];
+} PROCESSOR_POWER_POLICY, *PPROCESSOR_POWER_POLICY;
+
+typedef struct _ADMINISTRATOR_POWER_POLICY {
+ SYSTEM_POWER_STATE MinSleep;
+ SYSTEM_POWER_STATE MaxSleep;
+ DWORD MinVideoTimeout;
+ DWORD MaxVideoTimeout;
+ DWORD MinSpindownTimeout;
+ DWORD MaxSpindownTimeout;
+} ADMINISTRATOR_POWER_POLICY, *PADMINISTRATOR_POWER_POLICY;
+
+#endif /* WINVER >= 0x0500 */
+
+typedef VOID (NTAPI *WAITORTIMERCALLBACKFUNC)(PVOID,BOOLEAN);
+
+#ifdef UNICODE
+typedef OSVERSIONINFOW OSVERSIONINFO,*POSVERSIONINFO,*LPOSVERSIONINFO;
+typedef OSVERSIONINFOEXW OSVERSIONINFOEX,*POSVERSIONINFOEX,*LPOSVERSIONINFOEX;
+#else
+typedef OSVERSIONINFOA OSVERSIONINFO,*POSVERSIONINFO,*LPOSVERSIONINFO;
+typedef OSVERSIONINFOEXA OSVERSIONINFOEX,*POSVERSIONINFOEX,*LPOSVERSIONINFOEX;
+#endif
+
+#define VER_SET_CONDITION(lc,t,c) ((lc) = VerSetConditionMask((lc),(t),(c)))
+
+#if (_WIN32_WINNT >= 0x0500)
+ULONGLONG WINAPI VerSetConditionMask(ULONGLONG,DWORD,BYTE);
+#endif
+
+typedef enum _HEAP_INFORMATION_CLASS {
+ HeapCompatibilityInformation,
+ HeapEnableTerminationOnCorruption
+} HEAP_INFORMATION_CLASS;
+
+typedef enum _PROCESSOR_CACHE_TYPE {
+ CacheUnified,
+ CacheInstruction,
+ CacheData,
+ CacheTrace
+} PROCESSOR_CACHE_TYPE;
+
+typedef enum _LOGICAL_PROCESSOR_RELATIONSHIP {
+ RelationProcessorCore,
+ RelationNumaNode,
+ RelationCache,
+ RelationProcessorPackage,
+ RelationGroup,
+ RelationAll = 0xffff
+} LOGICAL_PROCESSOR_RELATIONSHIP;
+
+#define CACHE_FULLY_ASSOCIATIVE 0xFF
+
+typedef struct _CACHE_DESCRIPTOR {
+ BYTE Level;
+ BYTE Associativity;
+ WORD LineSize;
+ DWORD Size;
+ PROCESSOR_CACHE_TYPE Type;
+} CACHE_DESCRIPTOR, *PCACHE_DESCRIPTOR;
+
+typedef struct _SYSTEM_LOGICAL_PROCESSOR_INFORMATION {
+ ULONG_PTR ProcessorMask;
+ LOGICAL_PROCESSOR_RELATIONSHIP Relationship;
+ _ANONYMOUS_UNION union {
+ struct {
+ BYTE Flags;
+ } ProcessorCore;
+ struct {
+ DWORD NodeNumber;
+ } NumaNode;
+ CACHE_DESCRIPTOR Cache;
+ ULONGLONG Reserved[2];
+ } DUMMYUNIONNAME;
+} SYSTEM_LOGICAL_PROCESSOR_INFORMATION, *PSYSTEM_LOGICAL_PROCESSOR_INFORMATION;
+
+NTSYSAPI
+SIZE_T
+NTAPI
+RtlCompareMemory (
+ const VOID *Source1,
+ const VOID *Source2,
+ SIZE_T Length
+ );
+
+#define RtlMoveMemory memmove
+#define RtlCopyMemory memcpy
+#define RtlFillMemory(d,l,f) memset((d), (f), (l))
+#define RtlZeroMemory(d,l) RtlFillMemory((d),(l),0)
+
+FORCEINLINE
+PVOID
+RtlSecureZeroMemory(IN PVOID Buffer,
+ IN SIZE_T Length)
+{
+ volatile char *VolatilePointer;
+
+ /* Get a volatile pointer to prevent any compiler optimizations */
+ VolatilePointer = (volatile char *)Buffer;
+
+ /* Loop the whole buffer */
+ while (Length)
+ {
+ /* Zero the current byte and move on */
+ *VolatilePointer++ = 0;
+ Length--;
+ }
+
+ /* Return the pointer to ensure the compiler won't optimize this away */
+ return Buffer;
+}
+
+typedef struct _OBJECT_TYPE_LIST {
+ WORD Level;
+ WORD Sbz;
+ GUID *ObjectType;
+} OBJECT_TYPE_LIST, *POBJECT_TYPE_LIST;
+
+#if defined(__GNUC__)
+
+#if defined(_M_IX86)
+static __inline__ PVOID GetCurrentFiber(void)
+{
+ void* ret;
+ __asm__ __volatile__ (
+ "movl %%fs:0x10,%0"
+ : "=r" (ret) /* allow use of reg eax,ebx,ecx,edx,esi,edi */
+ );
+ return ret;
+}
+#elif defined (_M_AMD64)
+FORCEINLINE PVOID GetCurrentFiber(VOID)
+{
+ #ifdef NONAMELESSUNION
+ return (PVOID)__readgsqword(FIELD_OFFSET(NT_TIB, DUMMYUNIONNAME.FiberData));
+ #else
+ return (PVOID)__readgsqword(FIELD_OFFSET(NT_TIB, FiberData));
+ #endif
+}
+#elif defined (_M_ARM)
+ PVOID WINAPI GetCurrentFiber(VOID);
+#else
+#if defined(_M_PPC)
+static __inline__ __attribute__((always_inline)) unsigned long __readfsdword_winnt(const unsigned long Offset)
+{
+ unsigned long result;
+ __asm__("\tadd 7,13,%1\n"
+ "\tlwz %0,0(7)\n"
+ : "=r" (result)
+ : "r" (Offset)
+ : "r7");
+ return result;
+}
+
+#else
+#error Unknown architecture
+#endif
+static __inline__ PVOID GetCurrentFiber(void)
+{
+ return __readfsdword_winnt(0x10);
+}
+#endif
+
+#elif defined(__WATCOMC__)
+
+extern PVOID GetCurrentFiber(void);
+#pragma aux GetCurrentFiber = \
+ "mov eax, dword ptr fs:0x10" \
+ value [eax] \
+ modify [eax];
+
+#elif defined(_MSC_VER)
+
+#if (_MSC_FULL_VER >= 13012035)
+
+__inline PVOID GetCurrentFiber(void) { return (PVOID)(ULONG_PTR)__readfsdword(0x10); }
+
+#else
+
+static __inline PVOID GetCurrentFiber(void)
+{
+ PVOID p;
+ __asm mov eax, fs:[10h]
+ __asm mov [p], eax
+ return p;
+}
+
+#endif /* _MSC_FULL_VER */
+
+#endif /* __GNUC__/__WATCOMC__/_MSC_VER */
+
+#include "inline_ntcurrentteb.h"
+
+static __inline PVOID GetFiberData(void)
+{
+ return *((PVOID *)GetCurrentFiber());
+}
+
+#if defined(__GNUC__)
+
+static __inline__ BOOLEAN
+InterlockedBitTestAndSet(IN LONG volatile *Base,
+ IN LONG Bit)
+{
+#if defined(_M_IX86)
+ LONG OldBit;
+ __asm__ __volatile__("lock "
+ "btsl %2,%1\n\t"
+ "sbbl %0,%0\n\t"
+ :"=r" (OldBit),"+m" (*Base)
+ :"Ir" (Bit)
+ : "memory");
+ return OldBit;
+#else
+ return (_InterlockedOr(Base, 1 << Bit) >> Bit) & 1;
+#endif
+}
+
+static __inline__ BOOLEAN
+InterlockedBitTestAndReset(IN LONG volatile *Base,
+ IN LONG Bit)
+{
+#if defined(_M_IX86)
+ LONG OldBit;
+ __asm__ __volatile__("lock "
+ "btrl %2,%1\n\t"
+ "sbbl %0,%0\n\t"
+ :"=r" (OldBit),"+m" (*Base)
+ :"Ir" (Bit)
+ : "memory");
+ return OldBit;
+#else
+ return (_InterlockedAnd(Base, ~(1 << Bit)) >> Bit) & 1;
+#endif
+}
+
+#endif
+
+#define BitScanForward _BitScanForward
+#define BitScanReverse _BitScanReverse
+
+/* TODO: Other architectures than X86 */
+#if defined(_M_IX86)
+#define PF_TEMPORAL_LEVEL_1
+#define PF_NON_TEMPORAL_LEVEL_ALL
+#define PreFetchCacheLine(l, a)
+#elif defined (_M_AMD64)
+#define PreFetchCacheLine(l, a)
+#elif defined(_M_PPC)
+#define PreFetchCacheLine(l, a)
+#elif defined(_M_ARM)
+#define PreFetchCacheLine(l, a)
+#else
+#error Unknown architecture
+#endif
+
+/* TODO: Other architectures than X86 */
+#if defined(_M_IX86)
+#if defined(_MSC_VER)
+FORCEINLINE
+VOID
+MemoryBarrier (VOID)
+{
+ LONG Barrier;
+ __asm { xchg Barrier, eax }
+}
+#else
+FORCEINLINE
+VOID
+MemoryBarrier(VOID)
+{
+ LONG Barrier;
+ __asm__ __volatile__("xchgl %%eax, %[Barrier]" : : [Barrier] "m" (Barrier) : "memory");
+}
+#endif
+#elif defined (_M_AMD64)
+#define MemoryBarrier __faststorefence
+#elif defined(_M_PPC)
+#define MemoryBarrier()
+#elif defined(_M_ARM)
+#define MemoryBarrier()
+#else
+#error Unknown architecture
+#endif
+
+#if defined(_M_IX86)
++
+#ifdef _MSC_VER
++#pragma intrinsic(__int2c)
+#pragma intrinsic(_mm_pause)
+#define YieldProcessor _mm_pause
+#else
+#define YieldProcessor() __asm__ __volatile__("pause");
++#define __int2c() __asm__ __volatile__("int $0x2c");
+#endif
++
++
++FORCEINLINE
++VOID
++DbgRaiseAssertionFailure(VOID)
++{
++ __int2c();
++}
++
+#elif defined (_M_AMD64)
+#ifdef _MSC_VER
+#pragma intrinsic(_mm_pause)
+#define YieldProcessor _mm_pause
+#else
+#define YieldProcessor() __asm__ __volatile__("pause");
+#endif
+#elif defined(_M_PPC)
+#define YieldProcessor() __asm__ __volatile__("nop");
+#elif defined(_M_MIPS)
+#define YieldProcessor() __asm__ __volatile__("nop");
+#elif defined(_M_ARM)
+#define YieldProcessor __yield
+#else
+#error Unknown architecture
+#endif
+
+#if defined(_AMD64_)
+#if defined(_M_AMD64)
+
+#define InterlockedExchangeAddSizeT(a, b) InterlockedExchangeAdd64((LONG64 *)a, b)
+
+#define InterlockedAnd _InterlockedAnd
+#define InterlockedExchange _InterlockedExchange
+#define InterlockedOr _InterlockedOr
+
+#define InterlockedAnd64 _InterlockedAnd64
+#define InterlockedOr64 _InterlockedOr64
+
+#define InterlockedBitTestAndSet _interlockedbittestandset
+#define InterlockedBitTestAndSet64 _interlockedbittestandset64
+#define InterlockedBitTestAndReset _interlockedbittestandreset
+#define InterlockedBitTestAndReset64 _interlockedbittestandreset64
+
+
+#endif
+
+#else
+
+#define InterlockedExchangeAddSizeT(a, b) InterlockedExchangeAdd((LONG *)a, b)
+
+#endif
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif /* RC_INVOKED */
+
+#ifdef __cplusplus
+}
+#endif
+#endif
--- /dev/null
- __debugbreak();
+/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
+#include <precomp.h>
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <signal.h>
+
+static const char formatstr[] =
+ "Assertion failed!\n\n"
+ "Program: %s\n"
+ "File: %s\n"
+ "Line: %ld\n\n"
+ "Expression: %s\n"
+ "Press Retry to debug the application\n";
+
+
+/*
+ * @implemented
+ */
+void _assert(const char *exp, const char *file, unsigned line)
+{
+ int (WINAPI *pMessageBoxA)(HWND, LPCTSTR, LPCTSTR, UINT);
+ HMODULE hmodUser32;
+ char achProgram[40];
+ char *pszBuffer;
+ int len;
+ int iResult;
+
+ /* Assertion failed at foo.c line 45: x<y */
+ fprintf(stderr, "Assertion failed at %s line %d: %s\n", file, line, exp);
+ FIXME("Assertion failed at %s line %d: %s\n", file, line, exp);
+
+ /* Get MessageBoxA function pointer */
+ hmodUser32 = LoadLibrary("user32.dll");
+ pMessageBoxA = (PVOID)GetProcAddress(hmodUser32, "MessageBoxA");
+ if (!pMessageBoxA)
+ {
+ abort();
+ }
+
+ /* Get the file name of the module */
+ len = GetModuleFileNameA(NULL, achProgram, 40);
+
+ /* Calculate full length of the message */
+ len += sizeof(formatstr) + len + strlen(exp) + strlen(file);
+
+ /* Allocate a buffer */
+ pszBuffer = malloc(len + 1);
+
+ /* Format a message */
+ _snprintf(pszBuffer, len, formatstr, achProgram, file, line, exp);
+
+ /* Display a message box */
+ iResult = pMessageBoxA(NULL,
+ pszBuffer,
+ "ReactOS C Runtime Library",
+ MB_ABORTRETRYIGNORE | MB_ICONERROR);
+
+ free(pszBuffer);
+
+ /* Does the user want to abort? */
+ if (iResult == IDABORT)
+ {
+ abort();
+ }
+
+ /* Does the user want to debug? */
+ if (iResult == IDRETRY)
+ {
++ DbgRaiseAssertionFailure();
+ }
+}
--- /dev/null
- #define PTE_READONLY 0
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: BSD - See COPYING.ARM in the top level directory
+ * FILE: ntoskrnl/mm/ARM3/miarm.h
+ * PURPOSE: ARM Memory Manager Header
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ */
+
+#ifndef _M_AMD64
+
+#define MI_MIN_PAGES_FOR_NONPAGED_POOL_TUNING ((255 * _1MB) >> PAGE_SHIFT)
+#define MI_MIN_PAGES_FOR_SYSPTE_TUNING ((19 * _1MB) >> PAGE_SHIFT)
+#define MI_MIN_PAGES_FOR_SYSPTE_BOOST ((32 * _1MB) >> PAGE_SHIFT)
+#define MI_MAX_INIT_NONPAGED_POOL_SIZE (128 * _1MB)
+#define MI_MAX_NONPAGED_POOL_SIZE (128 * _1MB)
+#define MI_MAX_FREE_PAGE_LISTS 4
+
+#define MI_MIN_INIT_PAGED_POOLSIZE (32 * _1MB)
+
+#define MI_SESSION_VIEW_SIZE (20 * _1MB)
+#define MI_SESSION_POOL_SIZE (16 * _1MB)
+#define MI_SESSION_IMAGE_SIZE (8 * _1MB)
+#define MI_SESSION_WORKING_SET_SIZE (4 * _1MB)
+#define MI_SESSION_SIZE (MI_SESSION_VIEW_SIZE + \
+ MI_SESSION_POOL_SIZE + \
+ MI_SESSION_IMAGE_SIZE + \
+ MI_SESSION_WORKING_SET_SIZE)
+
+#define MI_SYSTEM_VIEW_SIZE (16 * _1MB)
+
+#define MI_SYSTEM_CACHE_WS_START (PVOID)0xC0C00000
+#define MI_PAGED_POOL_START (PVOID)0xE1000000
+#define MI_NONPAGED_POOL_END (PVOID)0xFFBE0000
+#define MI_DEBUG_MAPPING (PVOID)0xFFBFF000
+
+#define MI_SYSTEM_PTE_BASE (PVOID)MiAddressToPte(NULL)
+
+#define MI_MIN_SECONDARY_COLORS 8
+#define MI_SECONDARY_COLORS 64
+#define MI_MAX_SECONDARY_COLORS 1024
+
+#define MI_MIN_ALLOCATION_FRAGMENT (4 * _1KB)
+#define MI_ALLOCATION_FRAGMENT (64 * _1KB)
+#define MI_MAX_ALLOCATION_FRAGMENT (2 * _1MB)
+
+#define MM_HIGHEST_VAD_ADDRESS \
+ (PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE))
+#define MI_LOWEST_VAD_ADDRESS (PVOID)MM_LOWEST_USER_ADDRESS
+
+#endif /* !_M_AMD64 */
+
+/* Make the code cleaner with some definitions for size multiples */
+#define _1KB (1024u)
+#define _1MB (1024 * _1KB)
+#define _1GB (1024 * _1MB)
+
+/* Everyone loves 64K */
+#define _64K (64 * _1KB)
+
+/* Area mapped by a PDE */
+#define PDE_MAPPED_VA (PTE_COUNT * PAGE_SIZE)
+
+/* Size of a page table */
+#define PT_SIZE (PTE_COUNT * sizeof(MMPTE))
+
+/* Size of a page directory */
+#define PD_SIZE (PDE_COUNT * sizeof(MMPDE))
+
+/* Size of all page directories for a process */
+#define SYSTEM_PD_SIZE (PD_COUNT * PD_SIZE)
+
+/* Architecture specific count of PDEs in a directory, and count of PTEs in a PT */
+#ifdef _M_IX86
+#define PD_COUNT 1
+#define PDE_COUNT 1024
+#define PTE_COUNT 1024
+C_ASSERT(SYSTEM_PD_SIZE == PAGE_SIZE);
+#elif _M_ARM
+#define PD_COUNT 1
+#define PDE_COUNT 4096
+#define PTE_COUNT 256
+#else
+#define PD_COUNT PPE_PER_PAGE
+#define PDE_COUNT PDE_PER_PAGE
+#define PTE_COUNT PTE_PER_PAGE
+#endif
+
+#ifdef _M_IX86
+#define IMAGE_FILE_MACHINE_NATIVE IMAGE_FILE_MACHINE_I386
+#elif _M_ARM
+#define IMAGE_FILE_MACHINE_NATIVE IMAGE_FILE_MACHINE_ARM
+#elif _M_AMD64
+#define IMAGE_FILE_MACHINE_NATIVE IMAGE_FILE_MACHINE_AMD64
+#else
+#error Define these please!
+#endif
+
+//
+// Protection Bits part of the internal memory manager Protection Mask
+// Taken from http://www.reactos.org/wiki/Techwiki:Memory_management_in_the_Windows_XP_kernel
+// and public assertions.
+//
+#define MM_ZERO_ACCESS 0
+#define MM_READONLY 1
+#define MM_EXECUTE 2
+#define MM_EXECUTE_READ 3
+#define MM_READWRITE 4
+#define MM_WRITECOPY 5
+#define MM_EXECUTE_READWRITE 6
+#define MM_EXECUTE_WRITECOPY 7
+#define MM_NOCACHE 8
+#define MM_DECOMMIT 0x10
+#define MM_NOACCESS (MM_DECOMMIT | MM_NOCACHE)
+#define MM_INVALID_PROTECTION 0xFFFFFFFF
+
+//
+// Specific PTE Definitions that map to the Memory Manager's Protection Mask Bits
+// The Memory Manager's definition define the attributes that must be preserved
+// and these PTE definitions describe the attributes in the hardware sense. This
+// helps deal with hardware differences between the actual boolean expression of
+// the argument.
+//
+// For example, in the logical attributes, we want to express read-only as a flag
+// but on x86, it is writability that must be set. On the other hand, on x86, just
+// like in the kernel, it is disabling the caches that requires a special flag,
+// while on certain architectures such as ARM, it is enabling the cache which
+// requires a flag.
+//
+#if defined(_M_IX86) || defined(_M_AMD64)
+//
+// Access Flags
+//
- #define PTE_EXECUTE_READWRITE 0x0
++#define PTE_READONLY 0 // Doesn't exist on x86
+#define PTE_EXECUTE 0 // Not worrying about NX yet
+#define PTE_EXECUTE_READ 0 // Not worrying about NX yet
+#define PTE_READWRITE 0x2
+#define PTE_WRITECOPY 0x200
- #define MM_PTE_SOFTWARE_PROTECTION_BITS 5
++#define PTE_EXECUTE_READWRITE 0x2 // Not worrying about NX yet
+#define PTE_EXECUTE_WRITECOPY 0x200
+#define PTE_PROTOTYPE 0x400
+
+//
+// State Flags
+//
+#define PTE_VALID 0x1
+#define PTE_ACCESSED 0x20
+#define PTE_DIRTY 0x40
+
+//
+// Cache flags
+//
+#define PTE_ENABLE_CACHE 0
+#define PTE_DISABLE_CACHE 0x10
+#define PTE_WRITECOMBINED_CACHE 0x10
+#elif defined(_M_ARM)
++#define PTE_READONLY 0x200
++#define PTE_EXECUTE 0 // Not worrying about NX yet
++#define PTE_EXECUTE_READ 0 // Not worrying about NX yet
++#define PTE_READWRITE 0 // Doesn't exist on ARM
++#define PTE_WRITECOPY 0 // Doesn't exist on ARM
++#define PTE_EXECUTE_READWRITE 0 // Not worrying about NX yet
++#define PTE_EXECUTE_WRITECOPY 0 // Not worrying about NX yet
++#define PTE_PROTOTYPE 0x400 // Using the Shared bit
++//
++// Cache flags
++//
++#define PTE_ENABLE_CACHE 0
++#define PTE_DISABLE_CACHE 0x10
++#define PTE_WRITECOMBINED_CACHE 0x10
+#else
+#error Define these please!
+#endif
+
+extern const ULONG MmProtectToPteMask[32];
+extern const ULONG MmProtectToValue[32];
+
+//
+// Assertions for session images, addresses, and PTEs
+//
+#define MI_IS_SESSION_IMAGE_ADDRESS(Address) \
+ (((Address) >= MiSessionImageStart) && ((Address) < MiSessionImageEnd))
+
+#define MI_IS_SESSION_ADDRESS(Address) \
+ (((Address) >= MmSessionBase) && ((Address) < MiSessionSpaceEnd))
+
+#define MI_IS_SESSION_PTE(Pte) \
+ ((((PMMPTE)Pte) >= MiSessionBasePte) && (((PMMPTE)Pte) < MiSessionLastPte))
+
+#define MI_IS_PAGE_TABLE_ADDRESS(Address) \
+ (((PVOID)(Address) >= (PVOID)PTE_BASE) && ((PVOID)(Address) <= (PVOID)PTE_TOP))
+
+#define MI_IS_SYSTEM_PAGE_TABLE_ADDRESS(Address) \
+ (((Address) >= (PVOID)MiAddressToPte(MmSystemRangeStart)) && ((Address) <= (PVOID)PTE_TOP))
+
+#define MI_IS_PAGE_TABLE_OR_HYPER_ADDRESS(Address) \
+ (((PVOID)(Address) >= (PVOID)PTE_BASE) && ((PVOID)(Address) <= (PVOID)MmHyperSpaceEnd))
+
+//
+// Corresponds to MMPTE_SOFTWARE.Protection
+//
+#ifdef _M_IX86
+#define MM_PTE_SOFTWARE_PROTECTION_BITS 5
+#elif _M_ARM
- #ifdef _M_IX86
++#define MM_PTE_SOFTWARE_PROTECTION_BITS 6
+#elif _M_AMD64
+#define MM_PTE_SOFTWARE_PROTECTION_BITS 5
+#else
+#error Define these please!
+#endif
+
+//
+// Creates a software PTE with the given protection
+//
+#define MI_MAKE_SOFTWARE_PTE(p, x) ((p)->u.Long = (x << MM_PTE_SOFTWARE_PROTECTION_BITS))
+
+//
+// Marks a PTE as deleted
+//
+#define MI_SET_PFN_DELETED(x) ((x)->PteAddress = (PMMPTE)((ULONG_PTR)(x)->PteAddress | 1))
+#define MI_IS_PFN_DELETED(x) ((ULONG_PTR)((x)->PteAddress) & 1)
+
+//
+// Special values for LoadedImports
+//
+#define MM_SYSLDR_NO_IMPORTS (PVOID)0xFFFFFFFE
+#define MM_SYSLDR_BOOT_LOADED (PVOID)0xFFFFFFFF
+#define MM_SYSLDR_SINGLE_ENTRY 0x1
+
+#if defined(_M_IX86) || defined(_M_ARM)
+//
+// PFN List Sentinel
+//
+#define LIST_HEAD 0xFFFFFFFF
+
+//
+// Because GCC cannot automatically downcast 0xFFFFFFFF to lesser-width bits,
+// we need a manual definition suited to the number of bits in the PteFrame.
+// This is used as a LIST_HEAD for the colored list
+//
+#define COLORED_LIST_HEAD ((1 << 25) - 1) // 0x1FFFFFF
+#elif defined(_M_AMD64)
+#define LIST_HEAD 0xFFFFFFFFFFFFFFFFLL
+#define COLORED_LIST_HEAD ((1 << 57) - 1) // 0x1FFFFFFFFFFFFFFLL
+#else
+#error Define these please!
+#endif
+
+//
+// Special IRQL value (found in assertions)
+//
+#define MM_NOIRQL (KIRQL)0xFFFFFFFF
+
+//
+// Returns the color of a page
+//
+#define MI_GET_PAGE_COLOR(x) ((x) & MmSecondaryColorMask)
+#define MI_GET_NEXT_COLOR(x) (MI_GET_PAGE_COLOR(++MmSystemPageColor))
+#define MI_GET_NEXT_PROCESS_COLOR(x) (MI_GET_PAGE_COLOR(++(x)->NextPageColor))
+
- extern PMMPTE MmSystemPagePtes;
++#ifndef _M_AMD64
+//
+// Decodes a Prototype PTE into the underlying PTE
+//
+#define MiProtoPteToPte(x) \
+ (PMMPTE)((ULONG_PTR)MmPagedPoolStart + \
+ (((x)->u.Proto.ProtoAddressHigh << 7) | (x)->u.Proto.ProtoAddressLow))
+#endif
+
+//
+// Prototype PTEs that don't yet have a pagefile association
+//
+#define MI_PTE_LOOKUP_NEEDED 0xFFFFF
+
+//
+// System views are binned into 64K chunks
+//
+#define MI_SYSTEM_VIEW_BUCKET_SIZE _64K
+
+//
+// FIXFIX: These should go in ex.h after the pool merge
+//
+#ifdef _M_AMD64
+#define POOL_BLOCK_SIZE 16
+#else
+#define POOL_BLOCK_SIZE 8
+#endif
+#define POOL_LISTS_PER_PAGE (PAGE_SIZE / POOL_BLOCK_SIZE)
+#define BASE_POOL_TYPE_MASK 1
+#define POOL_MAX_ALLOC (PAGE_SIZE - (sizeof(POOL_HEADER) + POOL_BLOCK_SIZE))
+
+typedef struct _POOL_DESCRIPTOR
+{
+ POOL_TYPE PoolType;
+ ULONG PoolIndex;
+ ULONG RunningAllocs;
+ ULONG RunningDeAllocs;
+ ULONG TotalPages;
+ ULONG TotalBigPages;
+ ULONG Threshold;
+ PVOID LockAddress;
+ PVOID PendingFrees;
+ LONG PendingFreeDepth;
+ SIZE_T TotalBytes;
+ SIZE_T Spare0;
+ LIST_ENTRY ListHeads[POOL_LISTS_PER_PAGE];
+} POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;
+
+typedef struct _POOL_HEADER
+{
+ union
+ {
+ struct
+ {
+#ifdef _M_AMD64
+ ULONG PreviousSize:8;
+ ULONG PoolIndex:8;
+ ULONG BlockSize:8;
+ ULONG PoolType:8;
+#else
+ USHORT PreviousSize:9;
+ USHORT PoolIndex:7;
+ USHORT BlockSize:9;
+ USHORT PoolType:7;
+#endif
+ };
+ ULONG Ulong1;
+ };
+#ifdef _M_AMD64
+ ULONG PoolTag;
+#endif
+ union
+ {
+#ifdef _M_AMD64
+ PEPROCESS ProcessBilled;
+#else
+ ULONG PoolTag;
+#endif
+ struct
+ {
+ USHORT AllocatorBackTraceIndex;
+ USHORT PoolTagHash;
+ };
+ };
+} POOL_HEADER, *PPOOL_HEADER;
+
+C_ASSERT(sizeof(POOL_HEADER) == POOL_BLOCK_SIZE);
+C_ASSERT(POOL_BLOCK_SIZE == sizeof(LIST_ENTRY));
+
+extern ULONG ExpNumberOfPagedPools;
+extern POOL_DESCRIPTOR NonPagedPoolDescriptor;
+extern PPOOL_DESCRIPTOR ExpPagedPoolDescriptor[16 + 1];
+extern PVOID PoolTrackTable;
+
+//
+// END FIXFIX
+//
+
+typedef struct _MI_LARGE_PAGE_DRIVER_ENTRY
+{
+ LIST_ENTRY Links;
+ UNICODE_STRING BaseName;
+} MI_LARGE_PAGE_DRIVER_ENTRY, *PMI_LARGE_PAGE_DRIVER_ENTRY;
+
+typedef enum _MMSYSTEM_PTE_POOL_TYPE
+{
+ SystemPteSpace,
+ NonPagedPoolExpansion,
+ MaximumPtePoolTypes
+} MMSYSTEM_PTE_POOL_TYPE;
+
+typedef enum _MI_PFN_CACHE_ATTRIBUTE
+{
+ MiNonCached,
+ MiCached,
+ MiWriteCombined,
+ MiNotMapped
+} MI_PFN_CACHE_ATTRIBUTE, *PMI_PFN_CACHE_ATTRIBUTE;
+
+typedef struct _PHYSICAL_MEMORY_RUN
+{
+ ULONG BasePage;
+ ULONG PageCount;
+} PHYSICAL_MEMORY_RUN, *PPHYSICAL_MEMORY_RUN;
+
+typedef struct _PHYSICAL_MEMORY_DESCRIPTOR
+{
+ ULONG NumberOfRuns;
+ ULONG NumberOfPages;
+ PHYSICAL_MEMORY_RUN Run[1];
+} PHYSICAL_MEMORY_DESCRIPTOR, *PPHYSICAL_MEMORY_DESCRIPTOR;
+
+typedef struct _MMCOLOR_TABLES
+{
+ PFN_NUMBER Flink;
+ PVOID Blink;
+ PFN_NUMBER Count;
+} MMCOLOR_TABLES, *PMMCOLOR_TABLES;
+
+typedef struct _MI_LARGE_PAGE_RANGES
+{
+ PFN_NUMBER StartFrame;
+ PFN_NUMBER LastFrame;
+} MI_LARGE_PAGE_RANGES, *PMI_LARGE_PAGE_RANGES;
+
+typedef struct _MMVIEW
+{
+ ULONG_PTR Entry;
+ PCONTROL_AREA ControlArea;
+} MMVIEW, *PMMVIEW;
+
+typedef struct _MMSESSION
+{
+ KGUARDED_MUTEX SystemSpaceViewLock;
+ PKGUARDED_MUTEX SystemSpaceViewLockPointer;
+ PCHAR SystemSpaceViewStart;
+ PMMVIEW SystemSpaceViewTable;
+ ULONG SystemSpaceHashSize;
+ ULONG SystemSpaceHashEntries;
+ ULONG SystemSpaceHashKey;
+ ULONG BitmapFailures;
+ PRTL_BITMAP SystemSpaceBitMap;
+} MMSESSION, *PMMSESSION;
+
+extern MMPTE HyperTemplatePte;
+extern MMPDE ValidKernelPde;
+extern MMPTE ValidKernelPte;
+extern MMPDE DemandZeroPde;
+extern MMPTE DemandZeroPte;
+extern MMPTE PrototypePte;
+extern BOOLEAN MmLargeSystemCache;
+extern BOOLEAN MmZeroPageFile;
+extern BOOLEAN MmProtectFreedNonPagedPool;
+extern BOOLEAN MmTrackLockedPages;
+extern BOOLEAN MmTrackPtes;
+extern BOOLEAN MmDynamicPfn;
+extern BOOLEAN MmMirroring;
+extern BOOLEAN MmMakeLowMemory;
+extern BOOLEAN MmEnforceWriteProtection;
+extern SIZE_T MmAllocationFragment;
+extern ULONG MmConsumedPoolPercentage;
+extern ULONG MmVerifyDriverBufferType;
+extern ULONG MmVerifyDriverLevel;
+extern WCHAR MmVerifyDriverBuffer[512];
+extern WCHAR MmLargePageDriverBuffer[512];
+extern LIST_ENTRY MiLargePageDriverList;
+extern BOOLEAN MiLargePageAllDrivers;
+extern ULONG MmVerifyDriverBufferLength;
+extern ULONG MmLargePageDriverBufferLength;
+extern SIZE_T MmSizeOfNonPagedPoolInBytes;
+extern SIZE_T MmMaximumNonPagedPoolInBytes;
+extern PFN_NUMBER MmMaximumNonPagedPoolInPages;
+extern PFN_NUMBER MmSizeOfPagedPoolInPages;
+extern PVOID MmNonPagedSystemStart;
+extern PVOID MmNonPagedPoolStart;
+extern PVOID MmNonPagedPoolExpansionStart;
+extern PVOID MmNonPagedPoolEnd;
+extern SIZE_T MmSizeOfPagedPoolInBytes;
+extern PVOID MmPagedPoolStart;
+extern PVOID MmPagedPoolEnd;
+extern PVOID MmSessionBase;
+extern SIZE_T MmSessionSize;
+extern PMMPTE MmFirstReservedMappingPte, MmLastReservedMappingPte;
+extern PMMPTE MiFirstReservedZeroingPte;
+extern MI_PFN_CACHE_ATTRIBUTE MiPlatformCacheAttributes[2][MmMaximumCacheType];
+extern PPHYSICAL_MEMORY_DESCRIPTOR MmPhysicalMemoryBlock;
+extern SIZE_T MmBootImageSize;
+extern PMMPTE MmSystemPtesStart[MaximumPtePoolTypes];
+extern PMMPTE MmSystemPtesEnd[MaximumPtePoolTypes];
+extern PMEMORY_ALLOCATION_DESCRIPTOR MxFreeDescriptor;
+extern MEMORY_ALLOCATION_DESCRIPTOR MxOldFreeDescriptor;
+extern ULONG_PTR MxPfnAllocation;
+extern MM_PAGED_POOL_INFO MmPagedPoolInfo;
+extern RTL_BITMAP MiPfnBitMap;
+extern KGUARDED_MUTEX MmPagedPoolMutex;
+extern PVOID MmPagedPoolStart;
+extern PVOID MmPagedPoolEnd;
+extern PVOID MmNonPagedSystemStart;
+extern PVOID MiSystemViewStart;
+extern SIZE_T MmSystemViewSize;
+extern PVOID MmSessionBase;
+extern PVOID MiSessionSpaceEnd;
+extern PMMPTE MiSessionImagePteStart;
+extern PMMPTE MiSessionImagePteEnd;
+extern PMMPTE MiSessionBasePte;
+extern PMMPTE MiSessionLastPte;
+extern SIZE_T MmSizeOfPagedPoolInBytes;
- MiDetermineUserGlobalPteMask(IN PMMPTE PointerPte)
++extern PMMPDE MmSystemPagePtes;
+extern PVOID MmSystemCacheStart;
+extern PVOID MmSystemCacheEnd;
+extern MMSUPPORT MmSystemCacheWs;
+extern SIZE_T MmAllocatedNonPagedPool;
+extern ULONG_PTR MmSubsectionBase;
+extern ULONG MmSpecialPoolTag;
+extern PVOID MmHyperSpaceEnd;
+extern PMMWSL MmSystemCacheWorkingSetList;
+extern SIZE_T MmMinimumNonPagedPoolSize;
+extern ULONG MmMinAdditionNonPagedPoolPerMb;
+extern SIZE_T MmDefaultMaximumNonPagedPool;
+extern ULONG MmMaxAdditionNonPagedPoolPerMb;
+extern ULONG MmSecondaryColors;
+extern ULONG MmSecondaryColorMask;
+extern ULONG_PTR MmNumberOfSystemPtes;
+extern ULONG MmMaximumNonPagedPoolPercent;
+extern ULONG MmLargeStackSize;
+extern PMMCOLOR_TABLES MmFreePagesByColor[FreePageList + 1];
+extern ULONG MmProductType;
+extern MM_SYSTEMSIZE MmSystemSize;
+extern PKEVENT MiLowMemoryEvent;
+extern PKEVENT MiHighMemoryEvent;
+extern PKEVENT MiLowPagedPoolEvent;
+extern PKEVENT MiHighPagedPoolEvent;
+extern PKEVENT MiLowNonPagedPoolEvent;
+extern PKEVENT MiHighNonPagedPoolEvent;
+extern PFN_NUMBER MmLowMemoryThreshold;
+extern PFN_NUMBER MmHighMemoryThreshold;
+extern PFN_NUMBER MiLowPagedPoolThreshold;
+extern PFN_NUMBER MiHighPagedPoolThreshold;
+extern PFN_NUMBER MiLowNonPagedPoolThreshold;
+extern PFN_NUMBER MiHighNonPagedPoolThreshold;
+extern PFN_NUMBER MmMinimumFreePages;
+extern PFN_NUMBER MmPlentyFreePages;
+extern PFN_NUMBER MiExpansionPoolPagesInitialCharge;
+extern PFN_NUMBER MmResidentAvailablePages;
+extern PFN_NUMBER MmResidentAvailableAtInit;
+extern ULONG MmTotalFreeSystemPtes[MaximumPtePoolTypes];
+extern PFN_NUMBER MmTotalSystemDriverPages;
+extern PVOID MiSessionImageStart;
+extern PVOID MiSessionImageEnd;
+extern PMMPTE MiHighestUserPte;
+extern PMMPDE MiHighestUserPde;
+extern PFN_NUMBER MmSystemPageDirectory[PD_COUNT];
+extern PMMPTE MmSharedUserDataPte;
+extern LIST_ENTRY MmProcessList;
+extern BOOLEAN MmZeroingPageThreadActive;
+extern KEVENT MmZeroingPageEvent;
+extern ULONG MmSystemPageColor;
+extern ULONG MmProcessColorSeed;
+extern PMMWSL MmWorkingSetList;
+
+//
+// Figures out the hardware bits for a PTE
+//
+ULONG
+FORCEINLINE
- TempPte.u.Hard.Accessed = TRUE;
++MiDetermineUserGlobalPteMask(IN PVOID PointerPte)
+{
+ MMPTE TempPte;
+
+ /* Start fresh */
+ TempPte.u.Long = 0;
+
+ /* Make it valid and accessed */
+ TempPte.u.Hard.Valid = TRUE;
- if ((PointerPte <= MiHighestUserPte) ||
- ((PointerPte >= MiAddressToPde(NULL)) && (PointerPte <= MiHighestUserPde)))
++ MI_MAKE_ACCESSED_PAGE(&TempPte);
+
+ /* Is this for user-mode? */
- TempPte.u.Hard.Owner = TRUE;
++ if ((PointerPte <= (PVOID)MiHighestUserPte) ||
++ ((PointerPte >= (PVOID)MiAddressToPde(NULL)) &&
++ (PointerPte <= (PVOID)MiHighestUserPde)))
+ {
+ /* Set the owner bit */
- #ifdef _M_IX86
++ MI_MAKE_OWNER_PAGE(&TempPte);
+ }
+
+ /* FIXME: We should also set the global bit */
+
+ /* Return the protection */
+ return TempPte.u.Long;
+}
+
+//
+// Creates a valid kernel PTE with the given protection
+//
+FORCEINLINE
+VOID
+MI_MAKE_HARDWARE_PTE_KERNEL(IN PMMPTE NewPte,
+ IN PMMPTE MappingPte,
+ IN ULONG ProtectionMask,
+ IN PFN_NUMBER PageFrameNumber)
+{
+ /* Only valid for kernel, non-session PTEs */
+ ASSERT(MappingPte > MiHighestUserPte);
+ ASSERT(!MI_IS_SESSION_PTE(MappingPte));
+ ASSERT((MappingPte < (PMMPTE)PDE_BASE) || (MappingPte > (PMMPTE)PDE_TOP));
+
+ /* Start fresh */
+ *NewPte = ValidKernelPte;
+
+ /* Set the protection and page */
+ NewPte->u.Hard.PageFrameNumber = PageFrameNumber;
+ NewPte->u.Long |= MmProtectToPteMask[ProtectionMask];
+}
+
+//
+// Creates a valid PTE with the given protection
+//
+FORCEINLINE
+VOID
+MI_MAKE_HARDWARE_PTE(IN PMMPTE NewPte,
+ IN PMMPTE MappingPte,
+ IN ULONG ProtectionMask,
+ IN PFN_NUMBER PageFrameNumber)
+{
+ /* Set the protection and page */
+ NewPte->u.Long = MiDetermineUserGlobalPteMask(MappingPte);
+ NewPte->u.Long |= MmProtectToPteMask[ProtectionMask];
+ NewPte->u.Hard.PageFrameNumber = PageFrameNumber;
+}
+
+//
+// Creates a valid user PTE with the given protection
+//
+FORCEINLINE
+VOID
+MI_MAKE_HARDWARE_PTE_USER(IN PMMPTE NewPte,
+ IN PMMPTE MappingPte,
+ IN ULONG ProtectionMask,
+ IN PFN_NUMBER PageFrameNumber)
+{
+ /* Only valid for kernel, non-session PTEs */
+ ASSERT(MappingPte <= MiHighestUserPte);
+
+ /* Start fresh */
+ *NewPte = ValidKernelPte;
+
+ /* Set the protection and page */
+ NewPte->u.Hard.Owner = TRUE;
+ NewPte->u.Hard.PageFrameNumber = PageFrameNumber;
+ NewPte->u.Long |= MmProtectToPteMask[ProtectionMask];
+}
+
++#ifndef _M_AMD64
+//
+// Builds a Prototype PTE for the address of the PTE
+//
+FORCEINLINE
+VOID
+MI_MAKE_PROTOTYPE_PTE(IN PMMPTE NewPte,
+ IN PMMPTE PointerPte)
+{
+ ULONG_PTR Offset;
+
+ /* Mark this as a prototype */
+ NewPte->u.Long = 0;
+ NewPte->u.Proto.Prototype = 1;
+
+ /*
+ * Prototype PTEs are only valid in paged pool by design, this little trick
+ * lets us only use 28 bits for the adress of the PTE
+ */
+ Offset = (ULONG_PTR)PointerPte - (ULONG_PTR)MmPagedPoolStart;
+
+ /* 7 bits go in the "low", and the other 21 bits go in the "high" */
+ NewPte->u.Proto.ProtoAddressLow = Offset & 0x7F;
+ NewPte->u.Proto.ProtoAddressHigh = (Offset & 0xFFFFFF80) >> 7;
+ ASSERT(MiProtoPteToPte(NewPte) == PointerPte);
+}
+#endif
+
+//
+// Returns if the page is physically resident (ie: a large page)
+// FIXFIX: CISC/x86 only?
+//
+FORCEINLINE
+BOOLEAN
+MI_IS_PHYSICAL_ADDRESS(IN PVOID Address)
+{
+ PMMPDE PointerPde;
+
+ /* Large pages are never paged out, always physically resident */
+ PointerPde = MiAddressToPde(Address);
+ return ((PointerPde->u.Hard.LargePage) && (PointerPde->u.Hard.Valid));
+}
+
+//
+// Writes a valid PTE
+//
+VOID
+FORCEINLINE
+MI_WRITE_VALID_PTE(IN PMMPTE PointerPte,
+ IN MMPTE TempPte)
+{
+ /* Write the valid PTE */
+ ASSERT(PointerPte->u.Hard.Valid == 0);
+ ASSERT(TempPte.u.Hard.Valid == 1);
+ *PointerPte = TempPte;
+}
+
+//
+// Writes an invalid PTE
+//
+VOID
+FORCEINLINE
+MI_WRITE_INVALID_PTE(IN PMMPTE PointerPte,
+ IN MMPTE InvalidPte)
+{
+ /* Write the invalid PTE */
+ ASSERT(InvalidPte.u.Hard.Valid == 0);
+ *PointerPte = InvalidPte;
+}
+
++//
++// Writes a valid PDE
++//
++VOID
++FORCEINLINE
++MI_WRITE_VALID_PDE(IN PMMPDE PointerPde,
++ IN MMPDE TempPde)
++{
++ /* Write the valid PDE */
++ ASSERT(PointerPde->u.Hard.Valid == 0);
++ ASSERT(TempPde.u.Hard.Valid == 1);
++ *PointerPde = TempPde;
++}
++
++//
++// Writes an invalid PDE
++//
++VOID
++FORCEINLINE
++MI_WRITE_INVALID_PDE(IN PMMPDE PointerPde,
++ IN MMPDE InvalidPde)
++{
++ /* Write the invalid PDE */
++ ASSERT(InvalidPde.u.Hard.Valid == 0);
++ *PointerPde = InvalidPde;
++}
++
+//
+// Checks if the thread already owns a working set
+//
+FORCEINLINE
+BOOLEAN
+MM_ANY_WS_LOCK_HELD(IN PETHREAD Thread)
+{
+ /* If any of these are held, return TRUE */
+ return ((Thread->OwnsProcessWorkingSetExclusive) ||
+ (Thread->OwnsProcessWorkingSetShared) ||
+ (Thread->OwnsSystemWorkingSetExclusive) ||
+ (Thread->OwnsSystemWorkingSetShared) ||
+ (Thread->OwnsSessionWorkingSetExclusive) ||
+ (Thread->OwnsSessionWorkingSetShared));
+}
+
+//
+// Checks if the process owns the working set lock
+//
+FORCEINLINE
+BOOLEAN
+MI_WS_OWNER(IN PEPROCESS Process)
+{
+ /* Check if this process is the owner, and that the thread owns the WS */
+ return ((KeGetCurrentThread()->ApcState.Process == &Process->Pcb) &&
+ ((PsGetCurrentThread()->OwnsProcessWorkingSetExclusive) ||
+ (PsGetCurrentThread()->OwnsProcessWorkingSetShared)));
+}
+
+//
+// Locks the working set for the given process
+//
+FORCEINLINE
+VOID
+MiLockProcessWorkingSet(IN PEPROCESS Process,
+ IN PETHREAD Thread)
+{
+ /* Shouldn't already be owning the process working set */
+ ASSERT(Thread->OwnsProcessWorkingSetShared == FALSE);
+ ASSERT(Thread->OwnsProcessWorkingSetExclusive == FALSE);
+
+ /* Block APCs, make sure that still nothing is already held */
+ KeEnterGuardedRegion();
+ ASSERT(!MM_ANY_WS_LOCK_HELD(Thread));
+
+ /* FIXME: Actually lock it (we can't because Vm is used by MAREAs) */
+
+ /* FIXME: This also can't be checked because Vm is used by MAREAs) */
+ //ASSERT(Process->Vm.Flags.AcquiredUnsafe == 0);
+
+ /* Okay, now we can own it exclusively */
+ ASSERT(Thread->OwnsProcessWorkingSetExclusive == FALSE);
+ Thread->OwnsProcessWorkingSetExclusive = TRUE;
+}
+
+//
+// Unlocks the working set for the given process
+//
+FORCEINLINE
+VOID
+MiUnlockProcessWorkingSet(IN PEPROCESS Process,
+ IN PETHREAD Thread)
+{
+ /* Make sure this process really is owner, and it was a safe acquisition */
+ ASSERT(MI_WS_OWNER(Process));
+ /* This can't be checked because Vm is used by MAREAs) */
+ //ASSERT(Process->Vm.Flags.AcquiredUnsafe == 0);
+
+ /* The thread doesn't own it anymore */
+ ASSERT(Thread->OwnsProcessWorkingSetExclusive == TRUE);
+ Thread->OwnsProcessWorkingSetExclusive = FALSE;
+
+ /* FIXME: Actually release it (we can't because Vm is used by MAREAs) */
+
+ /* Unblock APCs */
+ KeLeaveGuardedRegion();
+}
+
+//
+// Locks the working set
+//
+FORCEINLINE
+VOID
+MiLockWorkingSet(IN PETHREAD Thread,
+ IN PMMSUPPORT WorkingSet)
+{
+ /* Block APCs */
+ KeEnterGuardedRegion();
+
+ /* Working set should be in global memory */
+ ASSERT(MI_IS_SESSION_ADDRESS((PVOID)WorkingSet) == FALSE);
+
+ /* Thread shouldn't already be owning something */
+ ASSERT(!MM_ANY_WS_LOCK_HELD(Thread));
+
+ /* FIXME: Actually lock it (we can't because Vm is used by MAREAs) */
+
+ /* Which working set is this? */
+ if (WorkingSet == &MmSystemCacheWs)
+ {
+ /* Own the system working set */
+ ASSERT((Thread->OwnsSystemWorkingSetExclusive == FALSE) &&
+ (Thread->OwnsSystemWorkingSetShared == FALSE));
+ Thread->OwnsSystemWorkingSetExclusive = TRUE;
+ }
+ else if (WorkingSet->Flags.SessionSpace)
+ {
+ /* We don't implement this yet */
+ UNIMPLEMENTED;
+ while (TRUE);
+ }
+ else
+ {
+ /* Own the process working set */
+ ASSERT((Thread->OwnsProcessWorkingSetExclusive == FALSE) &&
+ (Thread->OwnsProcessWorkingSetShared == FALSE));
+ Thread->OwnsProcessWorkingSetExclusive = TRUE;
+ }
+}
+
+//
+// Unlocks the working set
+//
+FORCEINLINE
+VOID
+MiUnlockWorkingSet(IN PETHREAD Thread,
+ IN PMMSUPPORT WorkingSet)
+{
+ /* Working set should be in global memory */
+ ASSERT(MI_IS_SESSION_ADDRESS((PVOID)WorkingSet) == FALSE);
+
+ /* Which working set is this? */
+ if (WorkingSet == &MmSystemCacheWs)
+ {
+ /* Release the system working set */
+ ASSERT((Thread->OwnsSystemWorkingSetExclusive == TRUE) ||
+ (Thread->OwnsSystemWorkingSetShared == TRUE));
+ Thread->OwnsSystemWorkingSetExclusive = FALSE;
+ }
+ else if (WorkingSet->Flags.SessionSpace)
+ {
+ /* We don't implement this yet */
+ UNIMPLEMENTED;
+ while (TRUE);
+ }
+ else
+ {
+ /* Release the process working set */
+ ASSERT((Thread->OwnsProcessWorkingSetExclusive) ||
+ (Thread->OwnsProcessWorkingSetShared));
+ Thread->OwnsProcessWorkingSetExclusive = FALSE;
+ }
+
+ /* FIXME: Actually release it (we can't because Vm is used by MAREAs) */
+
+ /* Unblock APCs */
+ KeLeaveGuardedRegion();
+}
+
+//
+// Returns the ProtoPTE inside a VAD for the given VPN
+//
+FORCEINLINE
+PMMPTE
+MI_GET_PROTOTYPE_PTE_FOR_VPN(IN PMMVAD Vad,
+ IN ULONG_PTR Vpn)
+{
+ PMMPTE ProtoPte;
+
+ /* Find the offset within the VAD's prototype PTEs */
+ ProtoPte = Vad->FirstPrototypePte + (Vpn - Vad->StartingVpn);
+ ASSERT(ProtoPte <= Vad->LastContiguousPte);
+ return ProtoPte;
+}
+
+//
+// Returns the PFN Database entry for the given page number
+// Warning: This is not necessarily a valid PFN database entry!
+//
+FORCEINLINE
+PMMPFN
+MI_PFN_ELEMENT(IN PFN_NUMBER Pfn)
+{
+ /* Get the entry */
+ return &MmPfnDatabase[Pfn];
+};
+
+BOOLEAN
+NTAPI
+MmArmInitSystem(
+ IN ULONG Phase,
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+);
+
+NTSTATUS
+NTAPI
+MiInitMachineDependent(
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+);
+
+VOID
+NTAPI
+MiComputeColorInformation(
+ VOID
+);
+
+VOID
+NTAPI
+MiMapPfnDatabase(
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+);
+
+VOID
+NTAPI
+MiInitializeColorTables(
+ VOID
+);
+
+VOID
+NTAPI
+MiInitializePfnDatabase(
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock
+);
+
+BOOLEAN
+NTAPI
+MiInitializeMemoryEvents(
+ VOID
+);
+
+PFN_NUMBER
+NTAPI
+MxGetNextPage(
+ IN PFN_NUMBER PageCount
+);
+
+PPHYSICAL_MEMORY_DESCRIPTOR
+NTAPI
+MmInitializeMemoryLimits(
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock,
+ IN PBOOLEAN IncludeType
+);
+
+PFN_NUMBER
+NTAPI
+MiPagesInLoaderBlock(
+ IN PLOADER_PARAMETER_BLOCK LoaderBlock,
+ IN PBOOLEAN IncludeType
+);
+
+VOID
+FASTCALL
+MiSyncARM3WithROS(
+ IN PVOID AddressStart,
+ IN PVOID AddressEnd
+);
+
+NTSTATUS
+NTAPI
+MmArmAccessFault(
+ IN BOOLEAN StoreInstruction,
+ IN PVOID Address,
+ IN KPROCESSOR_MODE Mode,
+ IN PVOID TrapInformation
+);
+
+NTSTATUS
+FASTCALL
+MiCheckPdeForPagedPool(
+ IN PVOID Address
+);
+
+VOID
+NTAPI
+MiInitializeNonPagedPool(
+ VOID
+);
+
+VOID
+NTAPI
+MiInitializeNonPagedPoolThresholds(
+ VOID
+);
+
+VOID
+NTAPI
+MiInitializePoolEvents(
+ VOID
+);
+
+VOID //
+NTAPI //
+InitializePool( //
+ IN POOL_TYPE PoolType,// FIXFIX: This should go in ex.h after the pool merge
+ IN ULONG Threshold //
+); //
+
+VOID
+NTAPI
+MiInitializeSystemPtes(
+ IN PMMPTE StartingPte,
+ IN ULONG NumberOfPtes,
+ IN MMSYSTEM_PTE_POOL_TYPE PoolType
+);
+
+PMMPTE
+NTAPI
+MiReserveSystemPtes(
+ IN ULONG NumberOfPtes,
+ IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType
+);
+
+VOID
+NTAPI
+MiReleaseSystemPtes(
+ IN PMMPTE StartingPte,
+ IN ULONG NumberOfPtes,
+ IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType
+);
+
+
+PFN_NUMBER
+NTAPI
+MiFindContiguousPages(
+ IN PFN_NUMBER LowestPfn,
+ IN PFN_NUMBER HighestPfn,
+ IN PFN_NUMBER BoundaryPfn,
+ IN PFN_NUMBER SizeInPages,
+ IN MEMORY_CACHING_TYPE CacheType
+);
+
+PVOID
+NTAPI
+MiCheckForContiguousMemory(
+ IN PVOID BaseAddress,
+ IN PFN_NUMBER BaseAddressPages,
+ IN PFN_NUMBER SizeInPages,
+ IN PFN_NUMBER LowestPfn,
+ IN PFN_NUMBER HighestPfn,
+ IN PFN_NUMBER BoundaryPfn,
+ IN MI_PFN_CACHE_ATTRIBUTE CacheAttribute
+);
+
+PMDL
+NTAPI
+MiAllocatePagesForMdl(
+ IN PHYSICAL_ADDRESS LowAddress,
+ IN PHYSICAL_ADDRESS HighAddress,
+ IN PHYSICAL_ADDRESS SkipBytes,
+ IN SIZE_T TotalBytes,
+ IN MI_PFN_CACHE_ATTRIBUTE CacheAttribute,
+ IN ULONG Flags
+);
+
+PVOID
+NTAPI
+MiMapLockedPagesInUserSpace(
+ IN PMDL Mdl,
+ IN PVOID BaseVa,
+ IN MEMORY_CACHING_TYPE CacheType,
+ IN PVOID BaseAddress
+);
+
+VOID
+NTAPI
+MiUnmapLockedPagesInUserSpace(
+ IN PVOID BaseAddress,
+ IN PMDL Mdl
+);
+
+VOID
+NTAPI
+MiInsertPageInList(
+ IN PMMPFNLIST ListHead,
+ IN PFN_NUMBER PageFrameIndex
+);
+
+VOID
+NTAPI
+MiUnlinkFreeOrZeroedPage(
+ IN PMMPFN Entry
+);
+
+PFN_NUMBER
+NTAPI
+MiAllocatePfn(
+ IN PMMPTE PointerPte,
+ IN ULONG Protection
+);
+
+VOID
+NTAPI
+MiInitializePfn(
+ IN PFN_NUMBER PageFrameIndex,
+ IN PMMPTE PointerPte,
+ IN BOOLEAN Modified
+);
+
+VOID
+NTAPI
+MiInitializePfnForOtherProcess(
+ IN PFN_NUMBER PageFrameIndex,
+ IN PMMPTE PointerPte,
+ IN PFN_NUMBER PteFrame
+);
+
+VOID
+NTAPI
+MiDecrementShareCount(
+ IN PMMPFN Pfn1,
+ IN PFN_NUMBER PageFrameIndex
+);
+
+VOID
+NTAPI
+MiDecrementReferenceCount(
+ IN PMMPFN Pfn1,
+ IN PFN_NUMBER PageFrameIndex
+);
+
+PFN_NUMBER
+NTAPI
+MiRemoveAnyPage(
+ IN ULONG Color
+);
+
+PFN_NUMBER
+NTAPI
+MiRemoveZeroPage(
+ IN ULONG Color
+);
+
+VOID
+NTAPI
+MiZeroPhysicalPage(
+ IN PFN_NUMBER PageFrameIndex
+);
+
+VOID
+NTAPI
+MiInsertPageInFreeList(
+ IN PFN_NUMBER PageFrameIndex
+);
+
+PFN_NUMBER
+NTAPI
+MiDeleteSystemPageableVm(
+ IN PMMPTE PointerPte,
+ IN PFN_NUMBER PageCount,
+ IN ULONG Flags,
+ OUT PPFN_NUMBER ValidPages
+);
+
+PLDR_DATA_TABLE_ENTRY
+NTAPI
+MiLookupDataTableEntry(
+ IN PVOID Address
+);
+
+VOID
+NTAPI
+MiInitializeDriverLargePageList(
+ VOID
+);
+
+VOID
+NTAPI
+MiInitializeLargePageSupport(
+ VOID
+);
+
+VOID
+NTAPI
+MiSyncCachedRanges(
+ VOID
+);
+
+BOOLEAN
+NTAPI
+MiIsPfnInUse(
+ IN PMMPFN Pfn1
+);
+
+PMMVAD
+NTAPI
+MiLocateAddress(
+ IN PVOID VirtualAddress
+);
+
+PMMADDRESS_NODE
+NTAPI
+MiCheckForConflictingNode(
+ IN ULONG_PTR StartVpn,
+ IN ULONG_PTR EndVpn,
+ IN PMM_AVL_TABLE Table
+);
+
+TABLE_SEARCH_RESULT
+NTAPI
+MiFindEmptyAddressRangeDownTree(
+ IN SIZE_T Length,
+ IN ULONG_PTR BoundaryAddress,
+ IN ULONG_PTR Alignment,
+ IN PMM_AVL_TABLE Table,
+ OUT PULONG_PTR Base,
+ OUT PMMADDRESS_NODE *Parent
+);
+
+NTSTATUS
+NTAPI
+MiFindEmptyAddressRangeInTree(
+ IN SIZE_T Length,
+ IN ULONG_PTR Alignment,
+ IN PMM_AVL_TABLE Table,
+ OUT PMMADDRESS_NODE *PreviousVad,
+ OUT PULONG_PTR Base
+);
+
+VOID
+NTAPI
+MiInsertVad(
+ IN PMMVAD Vad,
+ IN PEPROCESS Process
+);
+
+VOID
+NTAPI
+MiInsertNode(
+ IN PMM_AVL_TABLE Table,
+ IN PMMADDRESS_NODE NewNode,
+ PMMADDRESS_NODE Parent,
+ TABLE_SEARCH_RESULT Result
+);
+
+VOID
+NTAPI
+MiRemoveNode(
+ IN PMMADDRESS_NODE Node,
+ IN PMM_AVL_TABLE Table
+);
+
+PMMADDRESS_NODE
+NTAPI
+MiGetPreviousNode(
+ IN PMMADDRESS_NODE Node
+);
+
+PMMADDRESS_NODE
+NTAPI
+MiGetNextNode(
+ IN PMMADDRESS_NODE Node
+);
+
+BOOLEAN
+NTAPI
+MiInitializeSystemSpaceMap(
+ IN PVOID InputSession OPTIONAL
+);
+
+ULONG
+NTAPI
+MiMakeProtectionMask(
+ IN ULONG Protect
+);
+
+VOID
+NTAPI
+MiDeleteVirtualAddresses(
+ IN ULONG_PTR Va,
+ IN ULONG_PTR EndingAddress,
+ IN PMMVAD Vad
+);
+
+ULONG
+NTAPI
+MiMakeSystemAddressValid(
+ IN PVOID PageTableVirtualAddress,
+ IN PEPROCESS CurrentProcess
+);
+
+ULONG
+NTAPI
+MiMakeSystemAddressValidPfn(
+ IN PVOID VirtualAddress,
+ IN KIRQL OldIrql
+);
+
+VOID
+NTAPI
+MiRemoveMappedView(
+ IN PEPROCESS CurrentProcess,
+ IN PMMVAD Vad
+);
+
+PSUBSECTION
+NTAPI
+MiLocateSubsection(
+ IN PMMVAD Vad,
+ IN ULONG_PTR Vpn
+);
+
+//
+// MiRemoveZeroPage will use inline code to zero out the page manually if only
+// free pages are available. In some scenarios, we don't/can't run that piece of
+// code and would rather only have a real zero page. If we can't have a zero page,
+// then we'd like to have our own code to grab a free page and zero it out, by
+// using MiRemoveAnyPage. This macro implements this.
+//
+PFN_NUMBER
+FORCEINLINE
+MiRemoveZeroPageSafe(IN ULONG Color)
+{
+ if (MmFreePagesByColor[ZeroedPageList][Color].Flink != LIST_HEAD) return MiRemoveZeroPage(Color);
+ return 0;
+}
+
+//
+// New ARM3<->RosMM PAGE Architecture
+//
+#define MI_GET_ROS_DATA(x) ((PMMROSPFN)(x->RosMmData))
+#define MI_IS_ROS_PFN(x) (((x)->u4.AweAllocation == TRUE) && (MI_GET_ROS_DATA(x) != NULL))
+#define ASSERT_IS_ROS_PFN(x) ASSERT(MI_IS_ROS_PFN(x) == TRUE);
+typedef struct _MMROSPFN
+{
+ PMM_RMAP_ENTRY RmapListHead;
+ SWAPENTRY SwapEntry;
+} MMROSPFN, *PMMROSPFN;
+
+#define RosMmData AweReferenceCount
+
+/* EOF */
--- /dev/null
- @ fastcall -arch=i386,arm ExInterlockedCompareExchange64(ptr ptr ptr ptr)
- @ stdcall -arch=i386,arm ExInterlockedDecrementLong(ptr ptr)
- @ stdcall -arch=i386,arm ExInterlockedExchangeUlong(ptr long ptr)
+@ stdcall CcCanIWrite(ptr long long long)
+@ stdcall CcCopyRead(ptr ptr long long ptr ptr)
+@ stdcall CcCopyWrite(ptr ptr long long ptr)
+@ stdcall CcDeferWrite(ptr ptr ptr ptr long long)
+@ stdcall CcFastCopyRead(ptr long long long ptr ptr)
+@ stdcall CcFastCopyWrite(ptr long long ptr)
+@ extern CcFastMdlReadWait
+@ extern CcFastReadNotPossible
+@ extern CcFastReadWait
+@ stdcall CcFlushCache(ptr ptr long ptr)
+@ stdcall CcGetDirtyPages(ptr ptr ptr ptr)
+@ stdcall CcGetFileObjectFromBcb(ptr)
+@ stdcall CcGetFileObjectFromSectionPtrs(ptr)
+@ stdcall CcGetFlushedValidData(ptr long)
+@ stdcall CcGetLsnForFileObject(ptr ptr)
+@ stdcall CcInitializeCacheMap(ptr ptr long ptr ptr)
+@ stdcall CcIsThereDirtyData(ptr)
+@ stdcall CcMapData(ptr ptr long long ptr ptr)
+@ stdcall CcMdlRead(ptr ptr long ptr ptr)
+@ stdcall CcMdlReadComplete(ptr ptr)
+@ stdcall CcMdlWriteAbort(ptr ptr)
+@ stdcall CcMdlWriteComplete(ptr ptr ptr)
+@ stdcall CcPinMappedData(ptr ptr long long ptr)
+@ stdcall CcPinRead(ptr ptr long long ptr ptr)
+@ stdcall CcPrepareMdlWrite(ptr ptr long ptr ptr)
+@ stdcall CcPreparePinWrite(ptr ptr long long long ptr ptr)
+@ stdcall CcPurgeCacheSection(ptr ptr long long)
+@ stdcall CcRemapBcb(ptr)
+@ stdcall CcRepinBcb(ptr)
+@ stdcall CcScheduleReadAhead(ptr ptr long)
+@ stdcall CcSetAdditionalCacheAttributes(ptr long long)
+@ stdcall CcSetBcbOwnerPointer(ptr ptr)
+@ stdcall CcSetDirtyPageThreshold(ptr long)
+@ stdcall CcSetDirtyPinnedData(ptr ptr)
+@ stdcall CcSetFileSizes(ptr ptr)
+@ stdcall CcSetLogHandleForFile(ptr ptr ptr)
+@ stdcall CcSetReadAheadGranularity(ptr long)
+@ stdcall CcUninitializeCacheMap(ptr ptr ptr)
+@ stdcall CcUnpinData(ptr)
+@ stdcall CcUnpinDataForThread(ptr ptr)
+@ stdcall CcUnpinRepinnedBcb(ptr long ptr)
+@ stdcall CcWaitForCurrentLazyWriterActivity()
+@ stdcall CcZeroData(ptr ptr ptr long)
+@ stdcall CmRegisterCallback(ptr ptr ptr)
+@ stdcall CmUnRegisterCallback(long long)
+@ stdcall DbgBreakPoint()
+@ stdcall DbgBreakPointWithStatus(long)
+@ stdcall DbgCommandString(ptr ptr)
+@ stdcall DbgLoadImageSymbols(ptr ptr long)
+@ cdecl DbgPrint(str)
+@ cdecl DbgPrintEx(long long str)
+@ cdecl DbgPrintReturnControlC(str)
+@ stdcall DbgPrompt(str ptr long)
+@ stdcall DbgQueryDebugFilterState(long long)
+@ stdcall DbgSetDebugFilterState(long long long)
+@ stdcall -arch=x86_64 ExAcquireFastMutex(ptr)
+@ fastcall ExAcquireFastMutexUnsafe(ptr)
+@ stdcall ExAcquireResourceExclusiveLite(ptr long)
+@ stdcall ExAcquireResourceSharedLite(ptr long)
+@ fastcall ExAcquireRundownProtection(ptr) ExfAcquireRundownProtection
+@ fastcall ExAcquireRundownProtectionCacheAware(ptr) ExfAcquireRundownProtectionCacheAware
+@ fastcall ExAcquireRundownProtectionCacheAwareEx(ptr long) ExfAcquireRundownProtectionCacheAwareEx
+@ fastcall ExAcquireRundownProtectionEx(ptr long) ExfAcquireRundownProtectionEx
+@ stdcall ExAcquireSharedStarveExclusive(ptr long)
+@ stdcall ExAcquireSharedWaitForExclusive(ptr long)
+@ stdcall ExAllocateCacheAwareRundownProtection(long long)
+@ stdcall ExAllocateFromPagedLookasideList(ptr) ExiAllocateFromPagedLookasideList
+@ stdcall ExAllocatePool(long long)
+@ stdcall ExAllocatePoolWithQuota(long long)
+@ stdcall ExAllocatePoolWithQuotaTag(long long long)
+@ stdcall ExAllocatePoolWithTag(long long long)
+@ stdcall ExAllocatePoolWithTagPriority(long long long long)
+@ stdcall ExConvertExclusiveToSharedLite(ptr)
+@ stdcall ExCreateCallback(ptr ptr long long)
+@ stdcall ExDeleteNPagedLookasideList(ptr)
+@ stdcall ExDeletePagedLookasideList(ptr)
+@ stdcall ExDeleteResourceLite(ptr)
+@ extern ExDesktopObjectType
+@ stdcall ExDisableResourceBoostLite(ptr)
+@ fastcall ExEnterCriticalRegionAndAcquireFastMutexUnsafe(ptr)
+@ stdcall ExEnterCriticalRegionAndAcquireResourceExclusive(ptr)
+@ stdcall ExEnterCriticalRegionAndAcquireResourceShared(ptr)
+@ stdcall ExEnterCriticalRegionAndAcquireSharedWaitForExclusive(ptr)
+@ stdcall ExEnumHandleTable(ptr ptr ptr ptr)
+@ extern ExEventObjectType _ExEventObjectType
+@ stdcall ExExtendZone(ptr ptr long)
+@ stdcall ExFreeCacheAwareRundownProtection(ptr)
+@ stdcall ExFreePool(ptr)
+@ stdcall ExFreePoolWithTag(ptr long)
+@ stdcall ExFreeToPagedLookasideList(ptr ptr) ExiFreeToPagedLookasideList
+@ stdcall ExGetCurrentProcessorCounts(ptr ptr ptr)
+@ stdcall ExGetCurrentProcessorCpuUsage(ptr)
+@ stdcall ExGetExclusiveWaiterCount(ptr)
+@ stdcall ExGetPreviousMode()
+@ stdcall ExGetSharedWaiterCount(ptr)
+@ stdcall ExInitializeNPagedLookasideList(ptr ptr ptr long long long long)
+@ stdcall ExInitializePagedLookasideList(ptr ptr ptr long long long long)
+@ stdcall ExInitializeResourceLite(ptr)
+@ fastcall ExInitializeRundownProtection(ptr) ExfInitializeRundownProtection
+@ stdcall ExInitializeRundownProtectionCacheAware(ptr long)
+@ stdcall ExInitializeZone(ptr long ptr long)
+@ stdcall ExInterlockedAddLargeInteger(ptr long long ptr)
+@ fastcall -arch=i386,arm ExInterlockedAddLargeStatistic(ptr long)
+@ stdcall ExInterlockedAddUlong(ptr long ptr)
++@ fastcall -arch=i386 ExInterlockedCompareExchange64(ptr ptr ptr ptr)
++@ stdcall -arch=i386 ExInterlockedDecrementLong(ptr ptr)
++@ stdcall -arch=i386 ExInterlockedExchangeUlong(ptr long ptr)
+@ stdcall ExInterlockedExtendZone(ptr ptr long ptr)
+@ fastcall -arch=i386,arm ExInterlockedFlushSList(ptr)
+@ stdcall -arch=i386,arm ExInterlockedIncrementLong(ptr ptr)
+@ stdcall ExInterlockedInsertHeadList(ptr ptr ptr)
+@ stdcall ExInterlockedInsertTailList(ptr ptr ptr)
+@ stdcall ExInterlockedPopEntryList(ptr ptr)
+@ fastcall -arch=i386,arm ExInterlockedPopEntrySList(ptr ptr)
+@ stdcall ExInterlockedPushEntryList(ptr ptr ptr)
+@ fastcall -arch=i386,arm ExInterlockedPushEntrySList(ptr ptr ptr)
+@ stdcall ExInterlockedRemoveHeadList(ptr ptr)
+@ stdcall ExIsProcessorFeaturePresent(long)
+@ stdcall ExIsResourceAcquiredExclusiveLite(ptr)
+@ stdcall ExIsResourceAcquiredSharedLite(ptr)
+@ stdcall ExLocalTimeToSystemTime(ptr ptr)
+@ stdcall ExNotifyCallback(ptr ptr ptr)
+@ stdcall -arch=x86_64 ExQueryDepthSList(ptr)
+@ stdcall ExQueryPoolBlockSize(ptr ptr)
+@ stdcall ExQueueWorkItem(ptr long)
+@ stdcall ExRaiseAccessViolation()
+@ stdcall ExRaiseDatatypeMisalignment()
+@ stdcall ExRaiseException(ptr) RtlRaiseException
+@ stdcall ExRaiseHardError(long long long ptr long ptr)
+@ stdcall ExRaiseStatus(long) RtlRaiseStatus
+@ fastcall ExReInitializeRundownProtection(ptr) ExfReInitializeRundownProtection
+@ fastcall ExReInitializeRundownProtectionCacheAware(ptr) ExfReInitializeRundownProtectionCacheAware
+@ stdcall ExRegisterCallback(ptr ptr ptr)
+@ stdcall ExReinitializeResourceLite(ptr)
+@ stdcall -arch=x86_64 ExReleaseFastMutex(ptr)
+@ fastcall ExReleaseFastMutexUnsafe(ptr)
+@ fastcall ExReleaseFastMutexUnsafeAndLeaveCriticalRegion(ptr)
+@ fastcall ExReleaseResourceAndLeaveCriticalRegion(ptr)
+@ stdcall ExReleaseResourceForThreadLite(ptr long)
+@ fastcall ExReleaseResourceLite(ptr)
+@ fastcall ExReleaseRundownProtection(ptr) ExfReleaseRundownProtection
+@ fastcall ExReleaseRundownProtectionCacheAware(ptr) ExfReleaseRundownProtectionCacheAware
+@ fastcall ExReleaseRundownProtectionCacheAwareEx(ptr long) ExfReleaseRundownProtectionCacheAwareEx
+@ fastcall ExReleaseRundownProtectionEx(ptr long) ExfReleaseRundownProtectionEx
+@ fastcall ExRundownCompleted(ptr) ExfRundownCompleted
+@ fastcall ExRundownCompletedCacheAware(ptr) ExfRundownCompletedCacheAware
+@ extern ExSemaphoreObjectType _ExSemaphoreObjectType
+@ stdcall ExSetResourceOwnerPointer(ptr ptr)
+@ stdcall ExSetTimerResolution(long long)
+@ stdcall ExSizeOfRundownProtectionCacheAware()
+@ stdcall ExSystemExceptionFilter()
+@ stdcall ExSystemTimeToLocalTime(ptr ptr)
+@ stdcall -arch=x86_64 ExTryToAcquireFastMutex(ptr)
+@ stdcall ExUnregisterCallback(ptr)
+@ stdcall ExUuidCreate(ptr)
+@ stdcall ExVerifySuite(long)
+@ fastcall ExWaitForRundownProtectionRelease(ptr) ExfWaitForRundownProtectionRelease
+@ fastcall ExWaitForRundownProtectionReleaseCacheAware(ptr) ExfWaitForRundownProtectionReleaseCacheAware
+@ extern ExWindowStationObjectType
+@ fastcall ExfAcquirePushLockExclusive(ptr)
+@ fastcall ExfAcquirePushLockShared(ptr)
+@ fastcall -arch=i386,arm ExfInterlockedAddUlong(ptr long ptr)
+@ fastcall -arch=i386,arm ExfInterlockedCompareExchange64(ptr ptr ptr)
+@ fastcall -arch=i386,arm ExfInterlockedInsertHeadList(ptr ptr ptr)
+@ fastcall -arch=i386,arm ExfInterlockedInsertTailList(ptr ptr ptr)
+@ fastcall -arch=i386,arm ExfInterlockedPopEntryList(ptr ptr)
+@ fastcall -arch=i386,arm ExfInterlockedPushEntryList(ptr ptr ptr)
+@ fastcall -arch=i386,arm ExfInterlockedRemoveHeadList(ptr ptr)
+@ fastcall ExfReleasePushLock(ptr)
+@ fastcall ExfReleasePushLockExclusive(ptr)
+@ fastcall ExfReleasePushLockShared(ptr)
+@ fastcall ExfTryToWakePushLock(ptr)
+@ fastcall ExfUnblockPushLock(ptr ptr)
+@ stdcall -arch=x86_64 ExpInterlockedFlushSList(ptr)
+@ stdcall -arch=x86_64 ExpInterlockedPopEntrySList(ptr ptr)
+@ stdcall -arch=x86_64 ExpInterlockedPushEntrySList(ptr ptr)
+@ fastcall -arch=i386 Exfi386InterlockedDecrementLong(ptr)
+@ fastcall -arch=i386 Exfi386InterlockedExchangeUlong(ptr long)
+@ fastcall -arch=i386 Exfi386InterlockedIncrementLong(ptr)
+@ stdcall -arch=i386 Exi386InterlockedDecrementLong(ptr)
+@ stdcall -arch=i386 Exi386InterlockedExchangeUlong(ptr long long)
+@ stdcall -arch=i386 Exi386InterlockedIncrementLong(ptr)
+@ fastcall -arch=i386 ExiAcquireFastMutex(ptr) ExAcquireFastMutex
+@ fastcall -arch=i386 ExiReleaseFastMutex(ptr) ExReleaseFastMutex
+@ fastcall -arch=i386 ExiTryToAcquireFastMutex(ptr) ExTryToAcquireFastMutex
+@ stdcall FsRtlAcquireFileExclusive(ptr)
+;FsRtlAddBaseMcbEntry
+@ stdcall FsRtlAddLargeMcbEntry(ptr long long long long long long)
+@ stdcall FsRtlAddMcbEntry(ptr long long long)
+@ stdcall FsRtlAddToTunnelCache(ptr long long ptr ptr long long ptr)
+@ stdcall FsRtlAllocateFileLock(ptr ptr)
+@ stdcall FsRtlAllocatePool(long long)
+@ stdcall FsRtlAllocatePoolWithQuota(long long)
+@ stdcall FsRtlAllocatePoolWithQuotaTag(long long long)
+@ stdcall FsRtlAllocatePoolWithTag(long long long)
+@ stdcall FsRtlAllocateResource()
+@ stdcall FsRtlAreNamesEqual(ptr ptr long wstr)
+@ stdcall FsRtlBalanceReads(ptr)
+@ stdcall FsRtlCheckLockForReadAccess(ptr ptr)
+@ stdcall FsRtlCheckLockForWriteAccess(ptr ptr)
+@ stdcall FsRtlCheckOplock(ptr ptr ptr ptr ptr)
+@ stdcall FsRtlCopyRead(ptr ptr long long long ptr ptr ptr)
+@ stdcall FsRtlCopyWrite(ptr ptr long long long ptr ptr ptr)
+@ stdcall FsRtlCreateSectionForDataScan(ptr ptr ptr ptr long ptr ptr long long long)
+@ stdcall FsRtlCurrentBatchOplock(ptr)
+@ stdcall FsRtlDeleteKeyFromTunnelCache(ptr long long)
+@ stdcall FsRtlDeleteTunnelCache(ptr)
+@ stdcall FsRtlDeregisterUncProvider(ptr)
+@ stdcall FsRtlDissectDbcs(long ptr ptr ptr)
+@ stdcall FsRtlDissectName(long ptr ptr ptr)
+@ stdcall FsRtlDoesDbcsContainWildCards(ptr)
+@ stdcall FsRtlDoesNameContainWildCards(ptr)
+@ stdcall FsRtlFastCheckLockForRead(ptr ptr ptr long ptr ptr)
+@ stdcall FsRtlFastCheckLockForWrite(ptr ptr ptr long ptr ptr)
+@ stdcall FsRtlFastUnlockAll(ptr ptr ptr ptr)
+@ stdcall FsRtlFastUnlockAllByKey(ptr ptr ptr long ptr)
+@ stdcall FsRtlFastUnlockSingle(ptr ptr ptr ptr ptr long ptr long)
+@ stdcall FsRtlFindInTunnelCache(ptr long long ptr ptr ptr ptr ptr)
+@ stdcall FsRtlFreeFileLock(ptr)
+@ stdcall FsRtlGetFileSize(ptr ptr)
+;FsRtlGetNextBaseMcbEntry
+@ stdcall FsRtlGetNextFileLock(ptr long)
+@ stdcall FsRtlGetNextLargeMcbEntry(ptr long ptr ptr ptr)
+@ stdcall FsRtlGetNextMcbEntry(ptr long ptr ptr ptr)
+@ stdcall FsRtlIncrementCcFastReadNoWait()
+@ stdcall FsRtlIncrementCcFastReadNotPossible()
+@ stdcall FsRtlIncrementCcFastReadResourceMiss()
+@ stdcall FsRtlIncrementCcFastReadWait()
+;FsRtlInitializeBaseMcb
+@ stdcall FsRtlInitializeFileLock(ptr ptr ptr)
+@ stdcall FsRtlInitializeLargeMcb(ptr long)
+@ stdcall FsRtlInitializeMcb(ptr long)
+@ stdcall FsRtlInitializeOplock(ptr)
+@ stdcall FsRtlInitializeTunnelCache(ptr)
+@ stdcall FsRtlInsertPerFileObjectContext(ptr ptr)
+@ stdcall FsRtlInsertPerStreamContext(ptr ptr)
+@ stdcall FsRtlIsDbcsInExpression(ptr ptr)
+@ stdcall FsRtlIsFatDbcsLegal(long ptr long long long)
+@ stdcall FsRtlIsHpfsDbcsLegal(long ptr long long long)
+@ stdcall FsRtlIsNameInExpression(ptr ptr long wstr)
+@ stdcall FsRtlIsNtstatusExpected(long)
+@ stdcall FsRtlIsPagingFile(ptr)
+@ stdcall FsRtlIsTotalDeviceFailure(ptr)
+@ extern FsRtlLegalAnsiCharacterArray _FsRtlLegalAnsiCharacterArray
+;FsRtlLookupBaseMcbEntry
+@ stdcall FsRtlLookupLargeMcbEntry(ptr long long ptr ptr ptr ptr ptr)
+;FsRtlLookupLastBaseMcbEntry
+;FsRtlLookupLastBaseMcbEntryAndIndex
+@ stdcall FsRtlLookupLastLargeMcbEntry(ptr ptr ptr)
+@ stdcall FsRtlLookupLastLargeMcbEntryAndIndex(ptr ptr ptr ptr)
+@ stdcall FsRtlLookupLastMcbEntry(ptr ptr ptr)
+@ stdcall FsRtlLookupMcbEntry(ptr long ptr ptr ptr)
+@ stdcall FsRtlLookupPerFileObjectContext(ptr ptr ptr)
+@ stdcall FsRtlLookupPerStreamContextInternal(ptr ptr ptr)
+@ stdcall FsRtlMdlRead(ptr ptr long long ptr ptr)
+@ stdcall FsRtlMdlReadComplete(ptr ptr)
+@ stdcall FsRtlMdlReadCompleteDev(ptr ptr ptr)
+@ stdcall FsRtlMdlReadDev(ptr ptr long long ptr ptr ptr)
+@ stdcall FsRtlMdlWriteComplete(ptr ptr ptr)
+@ stdcall FsRtlMdlWriteCompleteDev(ptr ptr ptr ptr)
+@ stdcall FsRtlNormalizeNtstatus(long long)
+@ stdcall FsRtlNotifyChangeDirectory(ptr ptr ptr ptr long long ptr)
+@ stdcall FsRtlNotifyCleanup(ptr ptr ptr)
+@ stdcall FsRtlNotifyFilterChangeDirectory(ptr ptr ptr ptr long long long ptr ptr ptr ptr)
+@ stdcall FsRtlNotifyFilterReportChange(ptr ptr ptr long ptr ptr long long ptr ptr)
+@ stdcall FsRtlNotifyFullChangeDirectory(ptr ptr ptr ptr long long long ptr ptr ptr)
+@ stdcall FsRtlNotifyFullReportChange(ptr ptr ptr long ptr ptr long long ptr)
+@ stdcall FsRtlNotifyInitializeSync(ptr)
+@ stdcall FsRtlNotifyReportChange(ptr ptr ptr ptr long)
+@ stdcall FsRtlNotifyUninitializeSync(ptr)
+@ stdcall FsRtlNotifyVolumeEvent(ptr long)
+;FsRtlNumberOfRunsInBaseMcb
+@ stdcall FsRtlNumberOfRunsInLargeMcb(ptr)
+@ stdcall FsRtlNumberOfRunsInMcb(ptr)
+@ stdcall FsRtlOplockFsctrl(ptr ptr long)
+@ stdcall FsRtlOplockIsFastIoPossible(ptr)
+@ stdcall FsRtlPostPagingFileStackOverflow(ptr ptr ptr)
+@ stdcall FsRtlPostStackOverflow(ptr ptr ptr)
+@ stdcall FsRtlPrepareMdlWrite(ptr ptr long long ptr ptr)
+@ stdcall FsRtlPrepareMdlWriteDev(ptr ptr long long ptr ptr ptr)
+@ stdcall FsRtlPrivateLock(ptr ptr ptr ptr ptr long long long ptr ptr ptr long)
+@ stdcall FsRtlProcessFileLock(ptr ptr ptr)
+@ stdcall FsRtlRegisterFileSystemFilterCallbacks(ptr ptr)
+@ stdcall FsRtlRegisterUncProvider(ptr ptr long)
+@ stdcall FsRtlReleaseFile(ptr)
+;FsRtlRemoveBaseMcbEntry
+@ stdcall FsRtlRemoveLargeMcbEntry(ptr long long long long)
+@ stdcall FsRtlRemoveMcbEntry(ptr long long)
+@ stdcall FsRtlRemovePerFileObjectContext(ptr ptr ptr)
+@ stdcall FsRtlRemovePerStreamContext(ptr ptr ptr)
+;FsRtlResetBaseMcb
+@ stdcall FsRtlResetLargeMcb(ptr long)
+;FsRtlSplitBaseMcb
+@ stdcall FsRtlSplitLargeMcb(ptr long long long long)
+@ stdcall FsRtlSyncVolumes(long long long)
+@ stdcall FsRtlTeardownPerStreamContexts(ptr)
+;FsRtlTruncateBaseMcb
+@ stdcall FsRtlTruncateLargeMcb(ptr long long)
+@ stdcall FsRtlTruncateMcb(ptr long)
+;FsRtlUninitializeBaseMcb
+@ stdcall FsRtlUninitializeFileLock(ptr)
+@ stdcall FsRtlUninitializeLargeMcb(ptr)
+@ stdcall FsRtlUninitializeMcb(ptr)
+@ stdcall FsRtlUninitializeOplock(ptr)
+@ extern HalDispatchTable _HalDispatchTable
+@ fastcall HalExamineMBR(ptr long long ptr)
+@ extern HalPrivateDispatchTable
+;HeadlessDispatch
+@ stdcall InbvAcquireDisplayOwnership()
+@ stdcall InbvCheckDisplayOwnership()
+@ stdcall InbvDisplayString(str)
+@ stdcall InbvEnableBootDriver(long)
+@ stdcall InbvEnableDisplayString(long)
+@ stdcall InbvInstallDisplayStringFilter(ptr)
+@ stdcall InbvIsBootDriverInstalled()
+@ stdcall InbvNotifyDisplayOwnershipLost(ptr)
+@ stdcall InbvResetDisplay()
+@ stdcall InbvSetScrollRegion(long long long long)
+@ stdcall InbvSetTextColor(long)
+@ stdcall InbvSolidColorFill(long long long long long)
+@ extern InitSafeBootMode
+@ fastcall -arch=i386,arm InterlockedCompareExchange(ptr long long)
+@ fastcall -arch=i386,arm InterlockedDecrement(ptr)
+@ fastcall -arch=i386,arm InterlockedExchange(ptr long)
+@ fastcall -arch=i386,arm InterlockedExchangeAdd(ptr long)
+@ fastcall -arch=i386,arm InterlockedIncrement(ptr)
+@ fastcall -arch=i386,arm InterlockedPopEntrySList(ptr)
+@ fastcall -arch=i386,arm InterlockedPushEntrySList(ptr ptr)
+@ stdcall -arch=x86_64 InitializeSListHead(ptr) RtlInitializeSListHead
+@ stdcall IoAcquireCancelSpinLock(ptr)
+@ stdcall IoAcquireRemoveLockEx(ptr ptr str long long)
+@ stdcall IoAcquireVpbSpinLock(ptr)
+@ extern IoAdapterObjectType
+@ stdcall IoAllocateAdapterChannel(ptr ptr long ptr ptr)
+@ stdcall IoAllocateController(ptr ptr ptr ptr)
+@ stdcall IoAllocateDriverObjectExtension(ptr ptr long ptr)
+@ stdcall IoAllocateErrorLogEntry(ptr long)
+@ stdcall IoAllocateIrp(long long)
+@ stdcall IoAllocateMdl(ptr long long long ptr)
+@ stdcall IoAllocateWorkItem(ptr)
+@ fastcall IoAssignDriveLetters(ptr ptr ptr ptr)
+@ stdcall IoAssignResources(ptr ptr ptr ptr ptr ptr)
+@ stdcall IoAttachDevice(ptr ptr ptr)
+@ stdcall IoAttachDeviceByPointer(ptr ptr)
+@ stdcall IoAttachDeviceToDeviceStack(ptr ptr)
+@ stdcall IoAttachDeviceToDeviceStackSafe(ptr ptr ptr)
+@ stdcall IoBuildAsynchronousFsdRequest(long ptr ptr long ptr ptr)
+@ stdcall IoBuildDeviceIoControlRequest(long ptr ptr long ptr long long ptr ptr)
+@ stdcall IoBuildPartialMdl(ptr ptr ptr long)
+@ stdcall IoBuildSynchronousFsdRequest(long ptr ptr long ptr ptr ptr)
+@ stdcall IoCallDriver(ptr ptr)
+@ stdcall IoCancelFileOpen(ptr ptr)
+@ stdcall IoCancelIrp(ptr)
+@ stdcall IoCheckDesiredAccess(ptr long)
+@ stdcall IoCheckEaBufferValidity(ptr long ptr)
+@ stdcall IoCheckFunctionAccess(long long long long ptr ptr)
+@ stdcall IoCheckQuerySetFileInformation(long long long)
+@ stdcall IoCheckQuerySetVolumeInformation(long long long)
+@ stdcall IoCheckQuotaBufferValidity(ptr long ptr)
+@ stdcall IoCheckShareAccess(long long ptr ptr long)
+@ stdcall IoCompleteRequest(ptr long)
+@ stdcall IoConnectInterrupt(ptr ptr ptr ptr long long long long long long long)
+@ stdcall IoCreateController(long)
+@ stdcall IoCreateDevice(ptr long ptr long long long ptr)
+@ stdcall IoCreateDisk(ptr ptr)
+@ stdcall IoCreateDriver(ptr ptr)
+@ stdcall IoCreateFile(ptr long ptr ptr ptr long long long long ptr long long ptr long)
+@ stdcall IoCreateFileSpecifyDeviceObjectHint(ptr long ptr ptr ptr long long long long ptr long long ptr long ptr)
+@ stdcall IoCreateNotificationEvent(ptr ptr)
+@ stdcall IoCreateStreamFileObject(ptr ptr)
+@ stdcall IoCreateStreamFileObjectEx(ptr ptr ptr)
+@ stdcall IoCreateStreamFileObjectLite(ptr ptr)
+@ stdcall IoCreateSymbolicLink(ptr ptr)
+@ stdcall IoCreateSynchronizationEvent(ptr ptr)
+@ stdcall IoCreateUnprotectedSymbolicLink(ptr ptr)
+@ stdcall IoCsqInitialize(ptr ptr ptr ptr ptr ptr ptr)
+@ stdcall IoCsqInitializeEx(ptr ptr ptr ptr ptr ptr ptr)
+@ stdcall IoCsqInsertIrp(ptr ptr ptr)
+@ stdcall IoCsqInsertIrpEx(ptr ptr ptr ptr)
+@ stdcall IoCsqRemoveIrp(ptr ptr)
+@ stdcall IoCsqRemoveNextIrp(ptr ptr)
+@ stdcall IoDeleteController(ptr)
+@ stdcall IoDeleteDevice(ptr)
+@ stdcall IoDeleteDriver(ptr)
+@ stdcall IoDeleteSymbolicLink(ptr)
+@ stdcall IoDetachDevice(ptr)
+@ extern IoDeviceHandlerObjectSize
+@ extern IoDeviceHandlerObjectType
+@ extern IoDeviceObjectType
+@ stdcall IoDisconnectInterrupt(ptr)
+@ extern IoDriverObjectType
+@ stdcall IoEnqueueIrp(ptr)
+@ stdcall IoEnumerateDeviceObjectList(ptr ptr long ptr)
+@ stdcall IoEnumerateRegisteredFiltersList(ptr long ptr)
+@ stdcall IoFastQueryNetworkAttributes(ptr long long ptr ptr)
+@ extern IoFileObjectType _IoFileObjectType
+@ stdcall IoForwardAndCatchIrp(ptr ptr) IoForwardIrpSynchronously
+@ stdcall IoForwardIrpSynchronously(ptr ptr)
+@ stdcall IoFreeController(ptr)
+@ stdcall IoFreeErrorLogEntry(ptr)
+@ stdcall IoFreeIrp(ptr)
+@ stdcall IoFreeMdl(ptr)
+@ stdcall IoFreeWorkItem(ptr)
+@ stdcall IoGetAttachedDevice(ptr)
+@ stdcall IoGetAttachedDeviceReference(ptr)
+@ stdcall IoGetBaseFileSystemDeviceObject(ptr)
+@ stdcall IoGetBootDiskInformation(ptr long)
+@ stdcall IoGetConfigurationInformation()
+@ stdcall IoGetCurrentProcess()
+@ stdcall IoGetDeviceAttachmentBaseRef(ptr)
+@ stdcall IoGetDeviceInterfaceAlias(ptr ptr ptr)
+@ stdcall IoGetDeviceInterfaces(ptr ptr long ptr)
+@ stdcall IoGetDeviceObjectPointer(ptr long ptr ptr)
+@ stdcall IoGetDeviceProperty(ptr long long ptr ptr)
+@ stdcall IoGetDeviceToVerify(ptr)
+@ stdcall IoGetDiskDeviceObject(ptr ptr)
+@ stdcall IoGetDmaAdapter(ptr ptr ptr)
+@ stdcall IoGetDriverObjectExtension(ptr ptr)
+@ stdcall IoGetFileObjectGenericMapping()
+@ stdcall IoGetInitialStack()
+@ stdcall IoGetLowerDeviceObject(ptr)
+@ fastcall IoGetPagingIoPriority(ptr)
+@ stdcall IoGetRelatedDeviceObject(ptr)
+@ stdcall IoGetRequestorProcess(ptr)
+@ stdcall IoGetRequestorProcessId(ptr)
+@ stdcall IoGetRequestorSessionId(ptr ptr)
+@ stdcall IoGetStackLimits(ptr ptr)
+@ stdcall IoGetTopLevelIrp()
+@ stdcall IoInitializeIrp(ptr long long)
+@ stdcall IoInitializeRemoveLockEx(ptr long long long long)
+@ stdcall IoInitializeTimer(ptr ptr ptr)
+@ stdcall IoInvalidateDeviceRelations(ptr long)
+@ stdcall IoInvalidateDeviceState(ptr)
+@ stdcall -arch=x86_64 IoIs32bitProcess(ptr)
+@ stdcall IoIsFileOriginRemote(ptr)
+@ stdcall IoIsOperationSynchronous(ptr)
+@ stdcall IoIsSystemThread(ptr)
+@ stdcall IoIsValidNameGraftingBuffer(ptr ptr)
+@ stdcall IoIsWdmVersionAvailable(long long)
+@ stdcall IoMakeAssociatedIrp(ptr long)
+@ stdcall IoOpenDeviceInterfaceRegistryKey(ptr long ptr)
+@ stdcall IoOpenDeviceRegistryKey(ptr long long ptr)
+@ stdcall IoPageRead(ptr ptr ptr ptr ptr)
+@ stdcall IoPnPDeliverServicePowerNotification(long long long long)
+@ stdcall IoQueryDeviceDescription(ptr ptr ptr ptr ptr ptr ptr ptr)
+@ stdcall IoQueryFileDosDeviceName(ptr ptr)
+@ stdcall IoQueryFileInformation(ptr long long ptr ptr)
+@ stdcall IoQueryVolumeInformation(ptr long long ptr ptr)
+@ stdcall IoQueueThreadIrp(ptr)
+@ stdcall IoQueueWorkItem(ptr ptr long ptr)
+@ stdcall IoRaiseHardError(ptr ptr ptr)
+@ stdcall IoRaiseInformationalHardError(long ptr ptr)
+@ stdcall IoReadDiskSignature(ptr long ptr)
+@ extern IoReadOperationCount
+@ fastcall IoReadPartitionTable(ptr long long ptr)
+@ stdcall IoReadPartitionTableEx(ptr ptr)
+@ extern IoReadTransferCount
+@ stdcall IoRegisterBootDriverReinitialization(ptr ptr ptr)
+@ stdcall IoRegisterDeviceInterface(ptr ptr ptr ptr)
+@ stdcall IoRegisterDriverReinitialization(ptr ptr ptr)
+@ stdcall IoRegisterFileSystem(ptr)
+@ stdcall IoRegisterFsRegistrationChange(ptr ptr)
+@ stdcall IoRegisterLastChanceShutdownNotification(ptr)
+@ stdcall IoRegisterPlugPlayNotification(long long ptr ptr ptr ptr ptr)
+@ stdcall IoRegisterShutdownNotification(ptr)
+@ stdcall IoReleaseCancelSpinLock(long)
+@ stdcall IoReleaseRemoveLockAndWaitEx(ptr ptr long)
+@ stdcall IoReleaseRemoveLockEx(ptr ptr long)
+@ stdcall IoReleaseVpbSpinLock(long)
+@ stdcall IoRemoveShareAccess(ptr ptr)
+@ stdcall IoReportDetectedDevice(ptr long long long ptr ptr long ptr)
+@ stdcall IoReportHalResourceUsage(ptr ptr ptr long)
+@ stdcall IoReportResourceForDetection(ptr ptr long ptr ptr long ptr)
+@ stdcall IoReportResourceUsage(ptr ptr ptr long ptr ptr long long ptr)
+@ stdcall IoReportTargetDeviceChange(ptr ptr)
+@ stdcall IoReportTargetDeviceChangeAsynchronous(ptr ptr ptr ptr)
+@ stdcall IoRequestDeviceEject(ptr)
+@ stdcall IoReuseIrp(ptr long)
+@ stdcall IoSetCompletionRoutineEx(ptr ptr ptr ptr long long long)
+@ stdcall IoSetDeviceInterfaceState(ptr long)
+@ stdcall IoSetDeviceToVerify(ptr ptr)
+@ stdcall IoSetFileOrigin(ptr long)
+@ stdcall IoSetHardErrorOrVerifyDevice(ptr ptr)
+@ stdcall IoSetInformation(ptr ptr long ptr)
+@ stdcall IoSetIoCompletion(ptr ptr ptr long ptr long)
+@ fastcall IoSetPartitionInformation(ptr long long long)
+@ stdcall IoSetPartitionInformationEx(ptr long ptr)
+@ stdcall IoSetShareAccess(long long ptr ptr)
+@ stdcall IoSetStartIoAttributes(ptr long long)
+@ stdcall IoSetSystemPartition(ptr)
+@ stdcall IoSetThreadHardErrorMode(long)
+@ stdcall IoSetTopLevelIrp(ptr)
+@ stdcall IoStartNextPacket(ptr long)
+@ stdcall IoStartNextPacketByKey(ptr long long)
+@ stdcall IoStartPacket(ptr ptr ptr ptr)
+@ stdcall IoStartTimer(ptr)
+@ extern IoStatisticsLock
+@ stdcall IoStopTimer(ptr)
+@ stdcall IoSynchronousInvalidateDeviceRelations(ptr long)
+@ stdcall IoSynchronousPageWrite(ptr ptr ptr ptr ptr)
+@ stdcall IoThreadToProcess(ptr)
+@ stdcall IoTranslateBusAddress(long long long long ptr ptr)
+@ stdcall IoUnregisterFileSystem(ptr)
+@ stdcall IoUnregisterFsRegistrationChange(ptr ptr)
+@ stdcall IoUnregisterPlugPlayNotification(ptr)
+@ stdcall IoUnregisterShutdownNotification(ptr)
+@ stdcall IoUpdateShareAccess(ptr ptr)
+@ stdcall IoValidateDeviceIoControlAccess(ptr long)
+@ stdcall IoVerifyPartitionTable(ptr long)
+@ stdcall IoVerifyVolume(ptr long)
+@ stdcall IoVolumeDeviceToDosName(ptr ptr)
+@ stdcall IoWMIAllocateInstanceIds(ptr long ptr)
+@ stdcall IoWMIDeviceObjectToInstanceName(ptr ptr ptr)
+@ stdcall -arch=x86_64 IoWMIDeviceObjectToProviderId(ptr)
+@ stdcall IoWMIExecuteMethod(ptr ptr long long ptr ptr)
+@ stdcall IoWMIHandleToInstanceName(ptr ptr ptr)
+@ stdcall IoWMIOpenBlock(ptr long ptr)
+@ stdcall IoWMIQueryAllData(ptr ptr ptr)
+@ stdcall IoWMIQueryAllDataMultiple(ptr long ptr ptr)
+@ stdcall IoWMIQuerySingleInstance(ptr ptr ptr ptr)
+@ stdcall IoWMIQuerySingleInstanceMultiple(ptr ptr long ptr ptr)
+@ stdcall IoWMIRegistrationControl(ptr long)
+@ stdcall IoWMISetNotificationCallback(ptr ptr ptr)
+@ stdcall IoWMISetSingleInstance(ptr ptr long long ptr)
+@ stdcall IoWMISetSingleItem(ptr ptr long long long ptr)
+@ stdcall IoWMISuggestInstanceName(ptr ptr long ptr)
+@ stdcall IoWMIWriteEvent(ptr)
+@ stdcall IoWriteErrorLogEntry(ptr)
+@ extern IoWriteOperationCount
+@ fastcall IoWritePartitionTable(ptr long long long ptr)
+@ stdcall IoWritePartitionTableEx(ptr ptr)
+@ extern IoWriteTransferCount
+@ fastcall IofCallDriver(ptr ptr)
+@ fastcall IofCompleteRequest(ptr long)
+@ stdcall KdChangeOption(long long ptr long ptr ptr)
+@ extern KdDebuggerEnabled _KdDebuggerEnabled
+@ extern KdDebuggerNotPresent _KdDebuggerNotPresent
+@ stdcall KdDisableDebugger()
+@ stdcall KdEnableDebugger()
+@ extern KdEnteredDebugger
+@ stdcall KdPollBreakIn()
+@ stdcall KdPowerTransition(long)
+@ stdcall KdRefreshDebuggerNotPresent()
+@ stdcall KdSystemDebugControl(long ptr long ptr long ptr long)
+@ stdcall -arch=i386 Ke386CallBios(long ptr)
+@ stdcall -arch=i386 Ke386IoSetAccessProcess(ptr long)
+@ stdcall -arch=i386 Ke386QueryIoAccessMap(long ptr)
+@ stdcall -arch=i386 Ke386SetIoAccessMap(long ptr)
+@ fastcall KeAcquireGuardedMutex(ptr)
+@ fastcall KeAcquireGuardedMutexUnsafe(ptr)
+@ fastcall KeAcquireInStackQueuedSpinLockAtDpcLevel(ptr ptr)
+@ fastcall KeAcquireInStackQueuedSpinLockForDpc(ptr ptr)
+@ stdcall KeAcquireInterruptSpinLock(ptr)
+@ stdcall KeAcquireSpinLockAtDpcLevel(ptr)
+@ fastcall KeAcquireSpinLockForDpc(ptr)
+@ stdcall -arch=x86_64 KeAcquireSpinLockRaiseToDpc(ptr)
+@ stdcall KeAddSystemServiceTable(ptr ptr long ptr long)
+@ stdcall KeAreAllApcsDisabled()
+@ stdcall KeAreApcsDisabled()
+@ stdcall KeAttachProcess(ptr)
+@ stdcall KeBugCheck(long)
+@ stdcall KeBugCheckEx(long ptr ptr ptr ptr)
+@ stdcall KeCancelTimer(ptr)
+@ stdcall KeCapturePersistentThreadState(ptr long long long long long ptr)
+@ stdcall KeClearEvent(ptr)
+@ stdcall KeConnectInterrupt(ptr)
+@ stdcall KeDelayExecutionThread(long long ptr)
+@ stdcall KeDeregisterBugCheckCallback(ptr)
+@ stdcall KeDeregisterBugCheckReasonCallback(ptr)
+@ stdcall KeDeregisterNmiCallback(ptr)
+@ stdcall KeDetachProcess()
+@ stdcall KeDisconnectInterrupt(ptr)
+@ stdcall KeEnterCriticalRegion() _KeEnterCriticalRegion
+@ stdcall KeEnterGuardedRegion() _KeEnterGuardedRegion
+@ stdcall KeEnterKernelDebugger()
+@ stdcall KeFindConfigurationEntry(ptr long long ptr)
+@ stdcall KeFindConfigurationNextEntry(ptr long long ptr ptr)
+@ stdcall KeFlushEntireTb(long long)
+@ stdcall KeFlushQueuedDpcs()
+;KeGenericCallDpc
+@ stdcall KeGetCurrentThread()
+@ stdcall KeGetPreviousMode()
+@ stdcall KeGetRecommendedSharedDataAlignment()
+;KeI386AbiosCall
+@ stdcall -arch=i386 KeI386AllocateGdtSelectors(ptr long)
+; -arch=i386 KeI386Call16BitCStyleFunction
+; -arch=i386 KeI386Call16BitFunction
+@ stdcall -arch=i386 KeI386FlatToGdtSelector(long long long)
+; -arch=i386 KeI386GetLid
+@ extern -arch=i386 KeI386MachineType
+@ stdcall -arch=i386 KeI386ReleaseGdtSelectors(ptr long)
+; -arch=i386 KeI386ReleaseLid
+; -arch=i386 KeI386SetGdtSelector
+@ stdcall KeInitializeApc(ptr ptr long ptr ptr ptr long ptr)
+@ stdcall KeInitializeCrashDumpHeader(long long ptr long ptr)
+@ stdcall KeInitializeDeviceQueue(ptr)
+@ stdcall KeInitializeDpc(ptr ptr ptr)
+@ stdcall KeInitializeEvent(ptr long long)
+@ fastcall KeInitializeGuardedMutex(ptr)
+@ stdcall KeInitializeInterrupt(ptr ptr ptr ptr long long long long long long long)
+@ stdcall KeInitializeMutant(ptr long)
+@ stdcall KeInitializeMutex(ptr long)
+@ stdcall KeInitializeQueue(ptr long)
+@ stdcall KeInitializeSemaphore(ptr long long)
+@ stdcall -arch=i386,arm KeInitializeSpinLock(ptr) _KeInitializeSpinLock
+@ stdcall KeInitializeThreadedDpc(ptr ptr ptr)
+@ stdcall KeInitializeTimer(ptr)
+@ stdcall KeInitializeTimerEx(ptr long)
+@ stdcall KeInsertByKeyDeviceQueue(ptr ptr long)
+@ stdcall KeInsertDeviceQueue(ptr ptr)
+@ stdcall KeInsertHeadQueue(ptr ptr)
+@ stdcall KeInsertQueue(ptr ptr)
+@ stdcall KeInsertQueueApc(ptr ptr ptr long)
+@ stdcall KeInsertQueueDpc(ptr ptr ptr)
+@ stdcall KeInvalidateAllCaches()
+@ stdcall KeIpiGenericCall(ptr ptr)
+@ stdcall KeIsAttachedProcess()
+@ stdcall KeIsExecutingDpc()
+;KeIsWaitListEmpty
+@ stdcall KeLeaveCriticalRegion() _KeLeaveCriticalRegion
+@ stdcall KeLeaveGuardedRegion() _KeLeaveGuardedRegion
+@ extern KeLoaderBlock
+@ extern KeNumberProcessors
+@ stdcall KeProfileInterrupt(ptr)
+@ stdcall KeProfileInterruptWithSource(ptr long)
+@ stdcall KePulseEvent(ptr long long)
+@ stdcall KeQueryActiveProcessors()
+@ stdcall -arch=i386,arm KeQueryInterruptTime()
+@ stdcall KeQueryPriorityThread(ptr)
+@ stdcall KeQueryRuntimeThread(ptr ptr)
+@ stdcall -arch=i386,arm KeQuerySystemTime(ptr)
+@ stdcall KeQueryTickCount(ptr)
+@ stdcall KeQueryTimeIncrement()
+@ stdcall KeRaiseUserException(long)
+@ stdcall KeReadStateEvent(ptr)
+@ stdcall KeReadStateMutant(ptr)
+@ stdcall KeReadStateMutex(ptr) KeReadStateMutant
+@ stdcall KeReadStateQueue(ptr)
+@ stdcall KeReadStateSemaphore(ptr)
+@ stdcall KeReadStateTimer(ptr)
+@ stdcall KeRegisterBugCheckCallback(ptr ptr ptr long ptr)
+@ stdcall KeRegisterBugCheckReasonCallback(ptr ptr ptr ptr)
+@ stdcall KeRegisterNmiCallback(ptr ptr)
+@ fastcall KeReleaseGuardedMutex(ptr)
+@ fastcall KeReleaseGuardedMutexUnsafe(ptr)
+@ fastcall KeReleaseInStackQueuedSpinLockForDpc(ptr)
+@ fastcall KeReleaseInStackQueuedSpinLockFromDpcLevel(ptr)
+@ stdcall KeReleaseInterruptSpinLock(ptr long)
+@ stdcall KeReleaseMutant(ptr long long long)
+@ stdcall KeReleaseMutex(ptr long)
+@ stdcall KeReleaseSemaphore(ptr long long long)
+@ stdcall -arch=x86_64 KeReleaseSpinLock(ptr long)
+@ fastcall KeReleaseSpinLockForDpc(ptr long)
+@ stdcall KeReleaseSpinLockFromDpcLevel(ptr)
+@ stdcall KeRemoveByKeyDeviceQueue(ptr long)
+@ stdcall KeRemoveByKeyDeviceQueueIfBusy(ptr long)
+@ stdcall KeRemoveDeviceQueue(ptr)
+@ stdcall KeRemoveEntryDeviceQueue(ptr ptr)
+@ stdcall KeRemoveQueue(ptr long ptr)
+@ stdcall KeRemoveQueueDpc(ptr)
+@ stdcall KeRemoveSystemServiceTable(long)
+@ stdcall KeResetEvent(ptr)
+@ stdcall KeRestoreFloatingPointState(ptr)
+@ stdcall KeRevertToUserAffinityThread()
+@ stdcall KeRundownQueue(ptr)
+@ stdcall KeSaveFloatingPointState(ptr)
+@ cdecl KeSaveStateForHibernate(ptr)
+@ extern KeServiceDescriptorTable
+@ stdcall KeSetAffinityThread(ptr long)
+@ stdcall KeSetBasePriorityThread(ptr long)
+@ stdcall KeSetDmaIoCoherency(long)
+@ stdcall KeSetEvent(ptr long long)
+@ stdcall KeSetEventBoostPriority(ptr ptr)
+@ stdcall KeSetIdealProcessorThread(ptr long)
+@ stdcall KeSetImportanceDpc(ptr long)
+@ stdcall KeSetKernelStackSwapEnable(long)
+@ stdcall KeSetPriorityThread(ptr long)
+@ stdcall KeSetProfileIrql(long)
+@ stdcall KeSetSystemAffinityThread(long)
+@ stdcall KeSetTargetProcessorDpc(ptr long)
+@ stdcall KeSetTimeIncrement(long long)
+@ stdcall KeSetTimer(ptr long long ptr)
+@ stdcall KeSetTimerEx(ptr long long long ptr)
+;KeSignalCallDpcDone
+;KeSignalCallDpcSynchronize
+@ stdcall KeStackAttachProcess(ptr ptr)
+@ stdcall KeSynchronizeExecution(ptr ptr ptr)
+@ stdcall KeTerminateThread(long)
+@ fastcall KeTestSpinLock(ptr)
+@ extern KeTickCount
+@ fastcall KeTryToAcquireGuardedMutex(ptr)
+@ fastcall KeTryToAcquireSpinLockAtDpcLevel(ptr)
+@ stdcall KeUnstackDetachProcess(ptr)
+@ stdcall KeUpdateRunTime(ptr long)
+@ fastcall KeUpdateSystemTime(ptr long long)
+@ stdcall KeUserModeCallback(long ptr long ptr ptr)
+@ stdcall KeWaitForMultipleObjects(long ptr long long long long ptr ptr)
+@ stdcall KeWaitForMutexObject(ptr long long long ptr) KeWaitForSingleObject
+@ stdcall KeWaitForSingleObject(ptr long long long ptr)
+@ fastcall KefAcquireSpinLockAtDpcLevel(ptr)
+@ fastcall KefReleaseSpinLockFromDpcLevel(ptr)
+@ stdcall -arch=i386 Kei386EoiHelper()
+@ fastcall -arch=i386 KiEoiHelper(ptr)
+@ fastcall KiAcquireSpinLock(ptr)
+@ extern KiBugCheckData
+@ stdcall KiCheckForKernelApcDelivery()
+;KiCheckForSListAddress
+@ stdcall -arch=i386 KiCoprocessorError()
+@ stdcall KiDeliverApc(long ptr ptr)
+@ stdcall -arch=i386 KiDispatchInterrupt()
+@ extern KiEnableTimerWatchdog
+@ stdcall KiIpiServiceRoutine(ptr ptr)
+@ fastcall KiReleaseSpinLock(ptr)
+@ cdecl KiUnexpectedInterrupt()
+@ stdcall -arch=i386 Kii386SpinOnSpinLock(ptr long)
+@ stdcall LdrAccessResource(ptr ptr ptr ptr)
+@ stdcall LdrEnumResources(ptr ptr long ptr ptr)
+@ stdcall LdrFindResourceDirectory_U(ptr ptr long ptr)
+@ stdcall LdrFindResource_U(ptr ptr long ptr)
+@ extern LpcPortObjectType
+@ stdcall LpcRequestPort(ptr ptr)
+@ stdcall LpcRequestWaitReplyPort(ptr ptr ptr)
+@ stdcall LsaCallAuthenticationPackage(long long long long long long long)
+@ stdcall LsaDeregisterLogonProcess(long long)
+@ stdcall LsaFreeReturnBuffer(ptr)
+@ stdcall LsaLogonUser(ptr ptr long long ptr long ptr ptr ptr ptr ptr ptr ptr ptr)
+@ stdcall LsaLookupAuthenticationPackage(long long long)
+@ stdcall LsaRegisterLogonProcess(ptr ptr ptr)
+@ extern Mm64BitPhysicalAddress
+@ stdcall MmAddPhysicalMemory(ptr ptr)
+@ stdcall MmAddVerifierThunks(ptr long)
+@ stdcall MmAdjustWorkingSetSize(long long long long)
+@ stdcall MmAdvanceMdl(ptr long)
+@ stdcall MmAllocateContiguousMemory(long long long)
+@ stdcall MmAllocateContiguousMemorySpecifyCache(long long long long long long long long)
+@ stdcall MmAllocateMappingAddress(long long)
+@ stdcall MmAllocateNonCachedMemory(long)
+@ stdcall MmAllocatePagesForMdl(ptr ptr ptr ptr ptr ptr ptr)
+@ stdcall MmAllocatePagesForMdlEx(long long long long long long long long long)
+@ stdcall MmBuildMdlForNonPagedPool(ptr)
+@ stdcall MmCanFileBeTruncated(ptr ptr)
+;MmCommitSessionMappedView
+@ stdcall MmCreateMdl(ptr ptr long)
+;MmCreateMirror
+@ stdcall MmCreateSection(ptr long ptr ptr long long ptr ptr)
+@ stdcall MmDisableModifiedWriteOfSection(long)
+@ stdcall MmFlushImageSection(ptr long)
+@ stdcall MmForceSectionClosed(ptr long)
+@ stdcall MmFreeContiguousMemory(ptr)
+@ stdcall MmFreeContiguousMemorySpecifyCache(ptr long long)
+@ stdcall MmFreeMappingAddress(ptr long)
+@ stdcall MmFreeNonCachedMemory(ptr long)
+@ stdcall MmFreePagesFromMdl(ptr)
+@ stdcall MmGetPhysicalAddress(ptr)
+@ stdcall MmGetPhysicalMemoryRanges()
+@ stdcall MmGetSystemRoutineAddress(ptr)
+@ stdcall MmGetVirtualForPhysical(long long)
+@ stdcall MmGrowKernelStack(ptr)
+@ extern MmHighestUserAddress
+@ stdcall MmIsAddressValid(ptr)
+@ stdcall MmIsDriverVerifying(ptr)
+;MmIsIoSpaceActive
+@ stdcall MmIsNonPagedSystemAddressValid(ptr)
+@ stdcall MmIsRecursiveIoFault()
+@ stdcall MmIsThisAnNtAsSystem()
+@ stdcall MmIsVerifierEnabled(ptr)
+@ stdcall MmLockPagableDataSection(ptr) MmLockPageableDataSection
+@ stdcall MmLockPagableImageSection(ptr) MmLockPageableDataSection
+@ stdcall MmLockPagableSectionByHandle(ptr) MmLockPageableSectionByHandle
+@ stdcall MmMapIoSpace(long long long long)
+@ stdcall MmMapLockedPages(ptr long)
+@ stdcall MmMapLockedPagesSpecifyCache(ptr long long ptr long long)
+@ stdcall MmMapLockedPagesWithReservedMapping(ptr long ptr long)
+@ stdcall MmMapMemoryDumpMdl(ptr)
+@ stdcall MmMapUserAddressesToPage(ptr long ptr)
+@ stdcall MmMapVideoDisplay(long long long long)
+@ stdcall MmMapViewInSessionSpace(ptr ptr ptr)
+@ stdcall MmMapViewInSystemSpace(ptr ptr ptr)
+@ stdcall MmMapViewOfSection(ptr ptr ptr long long ptr ptr long long long)
+@ stdcall MmMarkPhysicalMemoryAsBad(ptr ptr)
+@ stdcall MmMarkPhysicalMemoryAsGood(ptr ptr)
+@ stdcall MmPageEntireDriver(ptr)
+@ stdcall MmPrefetchPages(long ptr)
+@ stdcall MmProbeAndLockPages(ptr long long)
+@ stdcall MmProbeAndLockProcessPages(ptr ptr long long)
+@ stdcall MmProbeAndLockSelectedPages(ptr ptr long long)
+@ stdcall MmProtectMdlSystemAddress(ptr long)
+@ stdcall MmQuerySystemSize()
+@ stdcall MmRemovePhysicalMemory(ptr ptr)
+@ stdcall MmResetDriverPaging(ptr)
+@ extern MmSectionObjectType
+@ stdcall MmSecureVirtualMemory(ptr long long)
+@ stdcall MmSetAddressRangeModified(ptr long)
+@ stdcall MmSetBankedSection(long long long long long long)
+@ stdcall MmSizeOfMdl(ptr long)
+@ extern MmSystemRangeStart
+@ stdcall MmTrimAllSystemPagableMemory(long) MmTrimAllSystemPageableMemory
+@ stdcall MmUnlockPagableImageSection(ptr) MmUnlockPageableImageSection
+@ stdcall MmUnlockPages(ptr)
+@ stdcall MmUnmapIoSpace(ptr long)
+@ stdcall MmUnmapLockedPages(ptr ptr)
+@ stdcall MmUnmapReservedMapping(ptr long ptr)
+@ stdcall MmUnmapVideoDisplay(ptr long)
+@ stdcall MmUnmapViewInSessionSpace(ptr)
+@ stdcall MmUnmapViewInSystemSpace(ptr)
+@ stdcall MmUnmapViewOfSection(ptr ptr)
+@ stdcall MmUnsecureVirtualMemory(ptr)
+@ extern MmUserProbeAddress
+@ extern NlsAnsiCodePage
+@ extern NlsLeadByteInfo
+@ extern NlsMbCodePageTag
+@ extern NlsMbOemCodePageTag
+@ extern NlsOemCodePage
+@ extern NlsOemLeadByteInfo _NlsOemLeadByteInfo
+@ stdcall NtAddAtom(wstr long ptr)
+@ stdcall NtAdjustPrivilegesToken(ptr long ptr long ptr ptr)
+@ stdcall NtAlertThread(ptr)
+@ stdcall NtAllocateLocallyUniqueId(ptr)
+@ stdcall NtAllocateUuids(ptr ptr ptr ptr)
+@ stdcall NtAllocateVirtualMemory(ptr ptr long ptr long long)
+@ extern NtBuildNumber
+@ stdcall NtClose(ptr)
+@ stdcall NtConnectPort(ptr ptr ptr ptr ptr ptr ptr ptr)
+@ stdcall NtCreateEvent(ptr long ptr long long)
+@ stdcall NtCreateFile(ptr long ptr ptr ptr long long long long ptr long)
+@ stdcall NtCreateSection(ptr long ptr ptr long long ptr)
+@ stdcall NtCreateTimer(ptr long ptr long)
+@ stdcall NtDeleteAtom(ptr)
+@ stdcall NtDeleteFile(ptr)
+@ stdcall NtDeviceIoControlFile(ptr ptr ptr ptr ptr long ptr long ptr long)
+@ stdcall NtDuplicateObject(ptr ptr ptr ptr long long long)
+@ stdcall NtDuplicateToken(ptr long ptr long long ptr)
+@ stdcall NtFindAtom(wstr long ptr)
+@ stdcall NtFreeVirtualMemory(ptr ptr ptr long)
+@ stdcall NtFsControlFile(ptr ptr ptr ptr ptr long ptr long ptr long)
+@ extern NtGlobalFlag
+@ stdcall NtLockFile(ptr ptr ptr ptr ptr ptr ptr long long long)
+@ stdcall NtMakePermanentObject(ptr)
+@ stdcall NtMapViewOfSection(ptr ptr ptr long long ptr ptr long long long)
+@ stdcall NtNotifyChangeDirectoryFile(ptr ptr ptr ptr ptr ptr long long long)
+@ stdcall NtOpenEvent(ptr long ptr)
+@ stdcall NtOpenFile(ptr long ptr ptr long long)
+@ stdcall NtOpenProcess(ptr long ptr ptr)
+@ stdcall NtOpenProcessToken(ptr long ptr)
+@ stdcall NtOpenProcessTokenEx(ptr long long ptr)
+@ stdcall NtOpenThread(ptr long ptr ptr)
+@ stdcall NtOpenThreadToken(ptr long long ptr)
+@ stdcall NtOpenThreadTokenEx(ptr long long long ptr)
+@ stdcall NtQueryDirectoryFile(ptr ptr ptr ptr ptr ptr long long long ptr long)
+@ stdcall NtQueryEaFile(ptr ptr ptr long long ptr long ptr long)
+@ stdcall NtQueryInformationAtom(ptr long ptr long ptr)
+@ stdcall NtQueryInformationFile(ptr ptr ptr long long)
+@ stdcall NtQueryInformationProcess(ptr ptr ptr long ptr)
+@ stdcall NtQueryInformationThread(ptr long ptr long ptr)
+@ stdcall NtQueryInformationToken(ptr long ptr long ptr)
+@ stdcall NtQueryQuotaInformationFile(ptr ptr ptr long long ptr long ptr long)
+@ stdcall NtQuerySecurityObject(ptr long ptr long ptr)
+@ stdcall NtQuerySystemInformation(long ptr long ptr)
+@ stdcall NtQueryVolumeInformationFile(ptr ptr ptr long long)
+@ stdcall NtReadFile(ptr ptr ptr ptr ptr ptr long ptr ptr)
+@ stdcall NtRequestPort(ptr ptr)
+@ stdcall NtRequestWaitReplyPort(ptr ptr ptr)
+@ stdcall NtSetEaFile(ptr ptr ptr long)
+@ stdcall NtSetEvent(ptr ptr)
+@ stdcall NtSetInformationFile(ptr ptr ptr long long)
+@ stdcall NtSetInformationProcess(ptr ptr ptr long)
+@ stdcall NtSetInformationThread(ptr long ptr long)
+@ stdcall NtSetQuotaInformationFile(ptr ptr ptr long)
+@ stdcall NtSetSecurityObject(ptr long ptr)
+@ stdcall NtSetVolumeInformationFile(ptr ptr ptr long long)
+@ stdcall NtShutdownSystem(long)
+@ stdcall NtTraceEvent(long long long ptr)
+@ stdcall NtUnlockFile(ptr ptr ptr ptr long)
+@ stdcall NtVdmControl(long ptr)
+@ stdcall NtWaitForSingleObject(ptr long ptr)
+@ stdcall NtWriteFile(ptr ptr ptr ptr ptr ptr long ptr ptr)
+@ stdcall ObAssignSecurity(ptr ptr ptr ptr)
+@ stdcall ObCheckCreateObjectAccess(ptr long ptr ptr long long ptr)
+@ stdcall ObCheckObjectAccess(ptr ptr long long ptr)
+@ stdcall ObCloseHandle(ptr long)
+@ stdcall ObCreateObject(long ptr ptr long ptr long long long ptr)
+@ stdcall ObCreateObjectType(ptr ptr ptr ptr)
+;ObDeleteCapturedInsertInfo
+@ stdcall ObDereferenceObject(ptr)
+@ stdcall ObDereferenceObjectDeferDelete(ptr)
+@ stdcall ObDereferenceSecurityDescriptor(ptr long)
+@ stdcall ObFindHandleForObject(ptr ptr ptr ptr ptr)
+@ stdcall ObGetObjectSecurity(ptr ptr ptr)
+@ stdcall ObInsertObject(ptr ptr long long ptr ptr)
+@ stdcall ObIsKernelHandle(ptr)
+@ stdcall ObLogSecurityDescriptor(ptr ptr long)
+@ stdcall ObMakeTemporaryObject(ptr)
+@ stdcall ObOpenObjectByName(ptr ptr long ptr long ptr ptr)
+@ stdcall ObOpenObjectByPointer(ptr long ptr long ptr long ptr)
+@ stdcall ObQueryNameString(ptr ptr long ptr)
+@ stdcall ObQueryObjectAuditingByHandle(ptr ptr)
+@ stdcall ObReferenceObjectByHandle(ptr long ptr long ptr ptr)
+@ stdcall ObReferenceObjectByName(ptr long ptr long ptr long ptr ptr)
+@ stdcall ObReferenceObjectByPointer(ptr long ptr long)
+@ stdcall ObReferenceSecurityDescriptor(ptr long)
+@ stdcall ObReleaseObjectSecurity(ptr long)
+;ObSetHandleAttributes@12
+@ stdcall ObSetSecurityDescriptorInfo(ptr ptr ptr ptr long ptr)
+@ stdcall ObSetSecurityObjectByPointer(ptr long ptr)
+@ fastcall ObfDereferenceObject(ptr)
+@ fastcall ObfReferenceObject(ptr)
+;PfxFindPrefix
+;PfxInitialize
+;PfxInsertPrefix
+;PfxRemovePrefix
+@ stdcall PoCallDriver(ptr ptr)
+@ stdcall PoCancelDeviceNotify(ptr)
+@ stdcall PoQueueShutdownWorkItem(ptr)
+@ stdcall PoRegisterDeviceForIdleDetection(ptr long long long)
+@ stdcall PoRegisterDeviceNotify(ptr long long long ptr ptr)
+@ stdcall PoRegisterSystemState(ptr long)
+@ stdcall PoRequestPowerIrp(ptr long long ptr ptr ptr)
+@ stdcall PoRequestShutdownEvent(ptr)
+@ stdcall PoSetHiberRange(ptr long ptr long long)
+@ stdcall PoSetPowerState(ptr long long)
+@ stdcall PoSetSystemState(long)
+@ stdcall PoShutdownBugCheck(long long ptr ptr ptr ptr)
+@ stdcall PoStartNextPowerIrp(ptr)
+@ stdcall PoUnregisterSystemState(ptr)
+@ stdcall ProbeForRead(ptr long long)
+@ stdcall ProbeForWrite(ptr long long)
+@ stdcall PsAssignImpersonationToken(ptr ptr)
+@ stdcall PsChargePoolQuota(ptr long long)
+@ stdcall PsChargeProcessNonPagedPoolQuota(ptr long)
+@ stdcall PsChargeProcessPagedPoolQuota(ptr long)
+@ stdcall PsChargeProcessPoolQuota(ptr long long)
+@ stdcall PsCreateSystemProcess(ptr long ptr)
+@ stdcall PsCreateSystemThread(ptr long ptr ptr ptr ptr ptr)
+@ stdcall PsDereferenceImpersonationToken(ptr) PsDereferencePrimaryToken
+@ stdcall PsDereferencePrimaryToken(ptr)
+@ stdcall PsDisableImpersonation(ptr ptr)
+@ stdcall PsEstablishWin32Callouts(ptr)
+@ stdcall PsGetContextThread(ptr ptr long)
+@ stdcall PsGetCurrentProcess() IoGetCurrentProcess
+@ stdcall PsGetCurrentProcessId()
+@ stdcall PsGetCurrentProcessSessionId()
+@ stdcall PsGetCurrentProcessWin32Process()
+@ stdcall PsGetCurrentThread() KeGetCurrentThread
+@ stdcall PsGetCurrentThreadId()
+@ stdcall PsGetCurrentThreadPreviousMode()
+;PsGetCurrentThreadProcess
+;PsGetCurrentThreadProcessId
+@ stdcall PsGetCurrentThreadStackBase()
+@ stdcall PsGetCurrentThreadStackLimit()
+;PsGetCurrentThreadTeb
+@ stdcall PsGetCurrentThreadWin32Thread()
+;PsGetCurrentThreadWin32ThreadAndEnterCriticalRegion
+@ stdcall PsGetJobLock(ptr)
+@ stdcall PsGetJobSessionId(ptr)
+@ stdcall PsGetJobUIRestrictionsClass(ptr)
+@ stdcall PsGetProcessCreateTimeQuadPart(ptr)
+@ stdcall PsGetProcessDebugPort(ptr)
+@ stdcall PsGetProcessExitProcessCalled(ptr)
+@ stdcall PsGetProcessExitStatus(ptr)
+@ stdcall PsGetProcessExitTime()
+@ stdcall PsGetProcessId(ptr)
+@ stdcall PsGetProcessImageFileName(ptr)
+@ stdcall PsGetProcessInheritedFromUniqueProcessId(ptr)
+@ stdcall PsGetProcessJob(ptr)
+@ stdcall PsGetProcessPeb(ptr)
+@ stdcall PsGetProcessPriorityClass(ptr)
+@ stdcall PsGetProcessSectionBaseAddress(ptr)
+@ stdcall PsGetProcessSecurityPort(ptr)
+@ stdcall PsGetProcessSessionId(ptr)
+;PsGetProcessSessionIdEx
+@ stdcall PsGetProcessWin32Process(ptr)
+@ stdcall PsGetProcessWin32WindowStation(ptr)
+@ stdcall PsGetThreadFreezeCount(ptr)
+@ stdcall PsGetThreadHardErrorsAreDisabled(ptr)
+@ stdcall PsGetThreadId(ptr)
+@ stdcall PsGetThreadProcess(ptr)
+@ stdcall PsGetThreadProcessId(ptr)
+@ stdcall PsGetThreadSessionId(ptr)
+@ stdcall PsGetThreadTeb(ptr)
+@ stdcall PsGetThreadWin32Thread(ptr)
+@ stdcall PsGetVersion(ptr ptr ptr ptr)
+@ stdcall PsImpersonateClient(ptr ptr long long long)
+@ extern PsInitialSystemProcess
+@ stdcall PsIsProcessBeingDebugged(ptr)
+@ stdcall PsIsSystemProcess(ptr)
+@ stdcall PsIsSystemThread(ptr)
+@ stdcall PsIsThreadImpersonating(ptr)
+@ stdcall PsIsThreadTerminating(ptr)
+@ extern PsJobType
+@ stdcall PsLookupProcessByProcessId(ptr ptr)
+@ stdcall PsLookupProcessThreadByCid(ptr ptr ptr)
+@ stdcall PsLookupThreadByThreadId(ptr ptr)
+@ extern PsProcessType _PsProcessType
+@ stdcall PsReferenceImpersonationToken(ptr ptr ptr ptr)
+@ stdcall PsReferencePrimaryToken(ptr)
+@ stdcall PsRemoveCreateThreadNotifyRoutine(ptr)
+@ stdcall PsRemoveLoadImageNotifyRoutine(ptr)
+@ stdcall PsRestoreImpersonation(ptr ptr)
+@ stdcall PsReturnPoolQuota(ptr long long)
+@ stdcall PsReturnProcessNonPagedPoolQuota(ptr long)
+@ stdcall PsReturnProcessPagedPoolQuota(ptr long)
+@ stdcall PsRevertThreadToSelf(ptr)
+@ stdcall PsRevertToSelf()
+@ stdcall PsSetContextThread(ptr ptr long)
+@ stdcall PsSetCreateProcessNotifyRoutine(ptr long)
+@ stdcall PsSetCreateThreadNotifyRoutine(ptr)
+@ stdcall PsSetJobUIRestrictionsClass(ptr long)
+@ stdcall PsSetLegoNotifyRoutine(ptr)
+@ stdcall PsSetLoadImageNotifyRoutine(ptr)
+@ stdcall PsSetProcessPriorityByClass(ptr ptr)
+@ stdcall PsSetProcessPriorityClass(ptr long)
+@ stdcall PsSetProcessSecurityPort(ptr ptr)
+@ stdcall PsSetProcessWin32Process(ptr ptr)
+@ stdcall PsSetProcessWindowStation(ptr ptr)
+@ stdcall PsSetThreadHardErrorsAreDisabled(ptr long)
+@ stdcall PsSetThreadWin32Thread(ptr ptr)
+@ stdcall PsTerminateSystemThread(long)
+@ extern PsThreadType _PsThreadType
+;PsWrapApcWow64Thread
+@ stdcall -arch=i386,arm READ_REGISTER_BUFFER_UCHAR(ptr ptr long)
+@ stdcall -arch=i386,arm READ_REGISTER_BUFFER_ULONG(ptr ptr long)
+@ stdcall -arch=i386,arm READ_REGISTER_BUFFER_USHORT(ptr ptr long)
+@ stdcall -arch=i386,arm READ_REGISTER_UCHAR(ptr)
+@ stdcall -arch=i386,arm READ_REGISTER_ULONG(ptr)
+@ stdcall -arch=i386,arm READ_REGISTER_USHORT(ptr)
+@ stdcall RtlAbsoluteToSelfRelativeSD(ptr ptr ptr)
+@ stdcall RtlAddAccessAllowedAce(ptr long long ptr)
+@ stdcall RtlAddAccessAllowedAceEx(ptr long long long ptr)
+@ stdcall RtlAddAce(ptr long long ptr long)
+@ stdcall RtlAddAtomToAtomTable(ptr wstr ptr)
+@ stdcall RtlAddRange(ptr long long long long long long ptr ptr)
+@ stdcall RtlAllocateAndInitializeSid(ptr long long long long long long long long long ptr)
+@ stdcall RtlAllocateHeap(ptr long long)
+@ stdcall RtlAnsiCharToUnicodeChar(ptr)
+@ stdcall RtlAnsiStringToUnicodeSize(ptr) RtlxAnsiStringToUnicodeSize
+@ stdcall RtlAnsiStringToUnicodeString(ptr ptr long)
+@ stdcall RtlAppendAsciizToString(ptr str)
+@ stdcall RtlAppendStringToString(ptr ptr)
+@ stdcall RtlAppendUnicodeStringToString(ptr ptr)
+@ stdcall RtlAppendUnicodeToString(ptr wstr)
+@ stdcall RtlAreAllAccessesGranted(long long)
+@ stdcall RtlAreAnyAccessesGranted(long long)
+@ stdcall RtlAreBitsClear(ptr long long)
+@ stdcall RtlAreBitsSet(ptr long long)
+@ stdcall RtlAssert(str str long str)
+@ stdcall RtlCaptureContext(ptr)
+@ stdcall RtlCaptureStackBackTrace(long long ptr ptr)
+@ stdcall RtlCharToInteger(str long ptr)
+@ stdcall RtlCheckRegistryKey(long wstr)
+@ stdcall RtlClearAllBits(ptr)
+@ stdcall RtlClearBit(ptr long)
+@ stdcall RtlClearBits(ptr long long)
+@ stdcall RtlCompareMemory(ptr ptr long)
+@ stdcall RtlCompareMemoryUlong(ptr long long)
+@ stdcall RtlCompareString(ptr ptr long)
+@ stdcall RtlCompareUnicodeString(ptr ptr long)
+@ stdcall RtlCompressBuffer(long ptr long ptr long long ptr ptr)
+@ stdcall RtlCompressChunks(ptr long ptr long ptr long ptr)
+@ stdcall RtlConvertLongToLargeInteger(long)
+@ stdcall RtlConvertSidToUnicodeString(ptr ptr long)
+@ stdcall RtlConvertUlongToLargeInteger(long)
+@ stdcall RtlCopyLuid(ptr ptr)
+@ stdcall RtlCopyRangeList(ptr ptr)
+@ stdcall RtlCopySid(long ptr ptr)
+@ stdcall RtlCopyString(ptr ptr)
+@ stdcall RtlCopyUnicodeString(ptr ptr)
+@ stdcall RtlCreateAcl(ptr long long)
+@ stdcall RtlCreateAtomTable(long ptr)
+@ stdcall RtlCreateHeap(long ptr long long ptr ptr)
+@ stdcall RtlCreateRegistryKey(long wstr)
+@ stdcall RtlCreateSecurityDescriptor(ptr long)
+@ stdcall RtlCreateSystemVolumeInformationFolder(ptr)
+@ stdcall RtlCreateUnicodeString(ptr wstr)
+@ stdcall RtlCustomCPToUnicodeN(ptr wstr long ptr ptr long)
+@ stdcall RtlDecompressBuffer(long ptr long ptr long ptr)
+@ stdcall RtlDecompressChunks(ptr long ptr long ptr long ptr)
+@ stdcall RtlDecompressFragment(long ptr long ptr long long ptr ptr)
+@ stdcall RtlDelete(ptr)
+@ stdcall RtlDeleteAce(ptr long)
+@ stdcall RtlDeleteAtomFromAtomTable(ptr ptr)
+@ stdcall RtlDeleteElementGenericTable(ptr ptr)
+@ stdcall RtlDeleteElementGenericTableAvl(ptr ptr)
+@ stdcall RtlDeleteNoSplay(ptr ptr)
+@ stdcall RtlDeleteOwnersRanges(ptr ptr)
+@ stdcall RtlDeleteRange(ptr long long long long ptr)
+@ stdcall RtlDeleteRegistryValue(long wstr wstr)
+@ stdcall RtlDescribeChunk(long ptr ptr ptr ptr)
+@ stdcall RtlDestroyAtomTable(ptr)
+@ stdcall RtlDestroyHeap(ptr)
+@ stdcall RtlDowncaseUnicodeString(ptr ptr long)
+@ stdcall RtlEmptyAtomTable(ptr long)
+@ stdcall RtlEnlargedIntegerMultiply(long long)
+@ stdcall RtlEnlargedUnsignedDivide(long long long ptr)
+@ stdcall RtlEnlargedUnsignedMultiply(long long)
+@ stdcall RtlEnumerateGenericTable(ptr long)
+@ stdcall RtlEnumerateGenericTableAvl(ptr long)
+@ stdcall RtlEnumerateGenericTableLikeADirectory(ptr ptr ptr long ptr ptr ptr)
+@ stdcall RtlEnumerateGenericTableWithoutSplaying(ptr ptr)
+@ stdcall RtlEnumerateGenericTableWithoutSplayingAvl(ptr ptr)
+@ stdcall RtlEqualLuid(ptr ptr)
+@ stdcall RtlEqualSid(ptr ptr)
+@ stdcall RtlEqualString(ptr ptr long)
+@ stdcall RtlEqualUnicodeString(ptr ptr long)
+@ stdcall RtlExtendedIntegerMultiply(long long long)
+@ stdcall RtlExtendedLargeIntegerDivide(long long long ptr)
+@ stdcall RtlExtendedMagicDivide(long long long long long)
+@ stdcall RtlFillMemory(ptr long long)
+@ stdcall RtlFillMemoryUlong(ptr long long)
+@ stdcall RtlFindClearBits(ptr long long)
+@ stdcall RtlFindClearBitsAndSet(ptr long long)
+@ stdcall RtlFindClearRuns(ptr ptr long long)
+@ stdcall RtlFindFirstRunClear(ptr ptr)
+@ stdcall RtlFindLastBackwardRunClear(ptr long ptr)
+@ stdcall RtlFindLeastSignificantBit(long long)
+@ stdcall RtlFindLongestRunClear(ptr ptr)
+@ stdcall RtlFindMessage(ptr long long long ptr)
+@ stdcall RtlFindMostSignificantBit(long long)
+@ stdcall RtlFindNextForwardRunClear(ptr long ptr)
+@ stdcall RtlFindRange(ptr long long long long long long long long ptr ptr ptr)
+@ stdcall RtlFindSetBits(ptr long long)
+@ stdcall RtlFindSetBitsAndClear(ptr long long)
+@ stdcall RtlFindUnicodePrefix(ptr ptr long)
+@ stdcall RtlFormatCurrentUserKeyPath(ptr)
+@ stdcall RtlFreeAnsiString(ptr)
+@ stdcall RtlFreeHeap(ptr long ptr)
+@ stdcall RtlFreeOemString(ptr)
+@ stdcall RtlFreeRangeList(ptr)
+@ stdcall RtlFreeUnicodeString(ptr)
+@ stdcall RtlGUIDFromString(ptr ptr)
+@ stdcall RtlGenerate8dot3Name(ptr ptr long ptr)
+@ stdcall RtlGetAce(ptr long ptr)
+@ stdcall RtlGetCallersAddress(ptr ptr)
+@ stdcall RtlGetCompressionWorkSpaceSize(long ptr ptr)
+@ stdcall RtlGetDaclSecurityDescriptor(ptr ptr ptr ptr)
+@ stdcall RtlGetDefaultCodePage(ptr ptr)
+@ stdcall RtlGetElementGenericTable(ptr long)
+@ stdcall RtlGetElementGenericTableAvl(ptr long)
+@ stdcall RtlGetFirstRange(ptr ptr ptr)
+@ stdcall RtlGetGroupSecurityDescriptor(ptr ptr ptr)
+@ stdcall RtlGetNextRange(ptr ptr long)
+@ stdcall RtlGetNtGlobalFlags()
+@ stdcall RtlGetOwnerSecurityDescriptor(ptr ptr ptr)
+@ stdcall RtlGetSaclSecurityDescriptor(ptr ptr ptr ptr)
+@ stdcall RtlGetSetBootStatusData(ptr long long ptr long long)
+@ stdcall RtlGetVersion(ptr)
+@ stdcall RtlHashUnicodeString(ptr long long ptr)
+@ stdcall RtlImageDirectoryEntryToData(ptr long long ptr)
+@ stdcall RtlImageNtHeader(ptr)
+@ stdcall RtlInitAnsiString(ptr str)
+@ stdcall RtlInitAnsiStringEx(ptr str)
+@ stdcall RtlInitCodePageTable(ptr ptr)
+@ stdcall RtlInitString(ptr str)
+@ stdcall RtlInitUnicodeString(ptr wstr)
+@ stdcall RtlInitUnicodeStringEx(ptr wstr)
+@ stdcall RtlInitializeBitMap(ptr ptr long)
+@ stdcall RtlInitializeGenericTable(ptr ptr ptr ptr ptr)
+@ stdcall RtlInitializeGenericTableAvl(ptr ptr ptr ptr ptr)
+@ stdcall RtlInitializeRangeList(ptr)
+@ stdcall RtlInitializeSid(ptr ptr long)
+@ stdcall RtlInitializeUnicodePrefix(ptr)
+@ stdcall RtlInsertElementGenericTable(ptr ptr long ptr)
+@ stdcall RtlInsertElementGenericTableAvl(ptr ptr long ptr)
+@ stdcall RtlInsertElementGenericTableFull(ptr ptr long ptr ptr long)
+@ stdcall RtlInsertElementGenericTableFullAvl(ptr ptr long ptr ptr ptr)
+@ stdcall RtlInsertUnicodePrefix(ptr ptr ptr)
+@ stdcall RtlInt64ToUnicodeString(long long long ptr)
+@ stdcall RtlIntegerToChar(long long long ptr)
+@ stdcall RtlIntegerToUnicode(long long long ptr)
+@ stdcall RtlIntegerToUnicodeString(long long ptr)
+@ stdcall RtlInvertRangeList(ptr ptr)
+@ stdcall RtlIpv4AddressToStringA(ptr ptr)
+@ stdcall RtlIpv4AddressToStringExA(ptr long ptr ptr)
+@ stdcall RtlIpv4AddressToStringExW(ptr long ptr ptr)
+@ stdcall RtlIpv4AddressToStringW(ptr ptr)
+@ stdcall RtlIpv4StringToAddressA(str long ptr ptr)
+@ stdcall RtlIpv4StringToAddressExA(str long ptr ptr)
+@ stdcall RtlIpv4StringToAddressExW(wstr long ptr ptr)
+@ stdcall RtlIpv4StringToAddressW(wstr long ptr ptr)
+@ stdcall RtlIpv6AddressToStringA(ptr ptr)
+@ stdcall RtlIpv6AddressToStringExA(ptr long long ptr ptr)
+@ stdcall RtlIpv6AddressToStringExW(ptr long long ptr ptr)
+@ stdcall RtlIpv6AddressToStringW(ptr ptr)
+@ stdcall RtlIpv6StringToAddressA(str ptr ptr)
+@ stdcall RtlIpv6StringToAddressExA(str ptr ptr ptr)
+@ stdcall RtlIpv6StringToAddressExW(wstr ptr ptr ptr)
+@ stdcall RtlIpv6StringToAddressW(wstr ptr ptr)
+@ stdcall RtlIsGenericTableEmpty(ptr)
+@ stdcall RtlIsGenericTableEmptyAvl(ptr)
+@ stdcall RtlIsNameLegalDOS8Dot3(ptr ptr ptr)
+@ stdcall RtlIsRangeAvailable(ptr long long long long long long ptr ptr ptr)
+@ stdcall RtlIsValidOemCharacter(ptr)
+@ stdcall RtlLargeIntegerAdd(long long long long)
+@ stdcall RtlLargeIntegerArithmeticShift(long long long)
+@ stdcall RtlLargeIntegerDivide(long long long long ptr)
+@ stdcall RtlLargeIntegerNegate(long long)
+@ stdcall RtlLargeIntegerShiftLeft(long long long)
+@ stdcall RtlLargeIntegerShiftRight(long long long)
+@ stdcall RtlLargeIntegerSubtract(long long long long)
+@ stdcall RtlLengthRequiredSid(long)
+@ stdcall RtlLengthSecurityDescriptor(ptr)
+@ stdcall RtlLengthSid(ptr)
+@ stdcall RtlLockBootStatusData(ptr)
+@ stdcall RtlLookupAtomInAtomTable(ptr wstr ptr)
+@ stdcall RtlLookupElementGenericTable(ptr ptr)
+@ stdcall RtlLookupElementGenericTableAvl(ptr ptr)
+@ stdcall RtlLookupElementGenericTableFull(ptr ptr ptr ptr)
+@ stdcall RtlLookupElementGenericTableFullAvl(ptr ptr ptr ptr)
+@ stdcall RtlMapGenericMask(ptr ptr)
+@ stdcall RtlMapSecurityErrorToNtStatus(long)
+@ stdcall RtlMergeRangeLists(ptr ptr ptr long)
+@ stdcall RtlMoveMemory(ptr ptr long)
+@ stdcall RtlMultiByteToUnicodeN(ptr long ptr str long)
+@ stdcall RtlMultiByteToUnicodeSize(ptr str long)
+@ stdcall RtlNextUnicodePrefix(ptr long)
+@ stdcall RtlNtStatusToDosError(long)
+@ stdcall RtlNtStatusToDosErrorNoTeb(long)
+@ stdcall RtlNumberGenericTableElements(ptr)
+@ stdcall RtlNumberGenericTableElementsAvl(ptr)
+@ stdcall RtlNumberOfClearBits(ptr)
+@ stdcall RtlNumberOfSetBits(ptr)
+@ stdcall RtlOemStringToCountedUnicodeString(ptr ptr long)
+@ stdcall RtlOemStringToUnicodeSize(ptr) RtlxOemStringToUnicodeSize
+@ stdcall RtlOemStringToUnicodeString(ptr ptr long)
+@ stdcall RtlOemToUnicodeN(wstr long ptr ptr long)
+@ stdcall RtlPinAtomInAtomTable(ptr ptr)
+@ fastcall RtlPrefetchMemoryNonTemporal(ptr long)
+@ stdcall RtlPrefixString(ptr ptr long)
+@ stdcall RtlPrefixUnicodeString(ptr ptr long)
+@ stdcall RtlQueryAtomInAtomTable(ptr ptr ptr ptr ptr ptr)
+@ stdcall RtlQueryRegistryValues(long wstr ptr ptr ptr)
+@ stdcall RtlQueryTimeZoneInformation(ptr)
+@ stdcall RtlRaiseException(ptr)
+@ stdcall RtlRandom(ptr)
+@ stdcall RtlRandomEx(ptr)
+@ stdcall RtlRealPredecessor(ptr)
+@ stdcall RtlRealSuccessor(ptr)
+@ stdcall RtlRemoveUnicodePrefix(ptr ptr)
+@ stdcall RtlReserveChunk(long ptr ptr ptr long)
+@ stdcall RtlSecondsSince1970ToTime(long ptr)
+@ stdcall RtlSecondsSince1980ToTime(long ptr)
+@ stdcall RtlSelfRelativeToAbsoluteSD(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr)
+@ stdcall RtlSelfRelativeToAbsoluteSD2(ptr long)
+@ stdcall RtlSetAllBits(ptr)
+@ stdcall RtlSetBit(ptr long)
+@ stdcall RtlSetBits(ptr long long)
+@ stdcall RtlSetDaclSecurityDescriptor(ptr long ptr long)
+@ stdcall RtlSetGroupSecurityDescriptor(ptr ptr long)
+@ stdcall RtlSetOwnerSecurityDescriptor(ptr ptr long)
+@ stdcall RtlSetSaclSecurityDescriptor(ptr long ptr long)
+@ stdcall RtlSetTimeZoneInformation(ptr)
+@ stdcall RtlSizeHeap(ptr long ptr)
+@ stdcall RtlSplay(ptr)
+@ stdcall RtlStringFromGUID(ptr ptr)
+@ stdcall RtlSubAuthorityCountSid(ptr)
+@ stdcall RtlSubAuthoritySid(ptr long)
+@ stdcall RtlSubtreePredecessor(ptr)
+@ stdcall RtlSubtreeSuccessor(ptr)
+@ stdcall RtlTestBit(ptr long)
+@ stdcall RtlTimeFieldsToTime(ptr ptr)
+@ stdcall RtlTimeToElapsedTimeFields(ptr ptr)
+@ stdcall RtlTimeToSecondsSince1970(ptr ptr)
+@ stdcall RtlTimeToSecondsSince1980(ptr ptr)
+@ stdcall RtlTimeToTimeFields(ptr ptr)
+;RtlTraceDatabaseAdd
+;RtlTraceDatabaseCreate
+;RtlTraceDatabaseDestroy
+;RtlTraceDatabaseEnumerate
+;RtlTraceDatabaseFind
+;RtlTraceDatabaseLock
+;RtlTraceDatabaseUnlock
+;RtlTraceDatabaseValidate
+@ fastcall -arch=i386,arm RtlUlongByteSwap(long)
+@ fastcall -arch=i386,arm RtlUlonglongByteSwap(long long)
+@ stdcall RtlUnicodeStringToAnsiSize(ptr) RtlxUnicodeStringToAnsiSize
+@ stdcall RtlUnicodeStringToAnsiString(ptr ptr long)
+@ stdcall RtlUnicodeStringToCountedOemString(ptr ptr long)
+@ stdcall RtlUnicodeStringToInteger(ptr long ptr)
+@ stdcall RtlUnicodeStringToOemSize(ptr) RtlxUnicodeStringToOemSize
+@ stdcall RtlUnicodeStringToOemString(ptr ptr long)
+@ stdcall RtlUnicodeToCustomCPN(ptr ptr long ptr wstr long)
+@ stdcall RtlUnicodeToMultiByteN(ptr long ptr wstr long)
+@ stdcall RtlUnicodeToMultiByteSize(ptr wstr long)
+@ stdcall RtlUnicodeToOemN(ptr long ptr wstr long)
+@ stdcall RtlUnlockBootStatusData(ptr)
+@ stdcall RtlUnwind(ptr ptr ptr ptr)
+@ stdcall RtlUpcaseUnicodeChar(long)
+@ stdcall RtlUpcaseUnicodeString(ptr ptr long)
+@ stdcall RtlUpcaseUnicodeStringToAnsiString(ptr ptr long)
+@ stdcall RtlUpcaseUnicodeStringToCountedOemString(ptr ptr long)
+@ stdcall RtlUpcaseUnicodeStringToOemString(ptr ptr long)
+@ stdcall RtlUpcaseUnicodeToCustomCPN(ptr ptr long ptr wstr long)
+@ stdcall RtlUpcaseUnicodeToMultiByteN(ptr long ptr wstr long)
+@ stdcall RtlUpcaseUnicodeToOemN(ptr long ptr wstr long)
+@ stdcall RtlUpperChar(long)
+@ stdcall RtlUpperString(ptr ptr)
+@ fastcall -arch=i386,arm RtlUshortByteSwap(long)
+@ stdcall RtlValidRelativeSecurityDescriptor(ptr long long)
+@ stdcall RtlValidSecurityDescriptor(ptr)
+@ stdcall RtlValidSid(ptr)
+@ stdcall RtlVerifyVersionInfo(ptr long long long)
+@ stdcall RtlVolumeDeviceToDosName(ptr ptr)
+@ stdcall RtlWalkFrameChain(ptr long long)
+@ stdcall RtlWriteRegistryValue(long wstr wstr long ptr long)
+@ stdcall RtlZeroHeap(ptr long)
+@ stdcall RtlZeroMemory(ptr long)
+@ stdcall RtlxAnsiStringToUnicodeSize(ptr)
+@ stdcall RtlxOemStringToUnicodeSize(ptr)
+@ stdcall RtlxUnicodeStringToAnsiSize(ptr)
+@ stdcall RtlxUnicodeStringToOemSize(ptr)
+@ stdcall SeAccessCheck(ptr ptr ptr long long ptr ptr long ptr ptr)
+@ stdcall SeAppendPrivileges(ptr ptr)
+@ stdcall SeAssignSecurity(ptr ptr ptr long ptr ptr ptr)
+@ stdcall SeAssignSecurityEx(ptr ptr ptr ptr long long ptr ptr ptr)
+@ stdcall SeAuditHardLinkCreation(ptr ptr long)
+@ stdcall SeAuditingFileEvents(long ptr)
+@ stdcall SeAuditingFileEventsWithContext(long ptr ptr)
+@ stdcall SeAuditingFileOrGlobalEvents(long ptr ptr)
+@ stdcall SeAuditingHardLinkEvents(long ptr)
+@ stdcall SeAuditingHardLinkEventsWithContext(long ptr ptr)
+@ stdcall SeCaptureSecurityDescriptor(ptr long long long ptr)
+@ stdcall SeCaptureSubjectContext(ptr)
+@ stdcall SeCloseObjectAuditAlarm(ptr ptr long)
+@ stdcall SeCreateAccessState(ptr ptr long ptr)
+@ stdcall SeCreateClientSecurity(ptr ptr long ptr)
+@ stdcall SeCreateClientSecurityFromSubjectContext(ptr ptr long ptr)
+@ stdcall SeDeassignSecurity(ptr)
+@ stdcall SeDeleteAccessState(ptr)
+@ stdcall SeDeleteObjectAuditAlarm(ptr ptr)
+@ extern SeExports
+@ stdcall SeFilterToken(ptr long ptr ptr ptr ptr)
+@ stdcall SeFreePrivileges(ptr)
+@ stdcall SeImpersonateClient(ptr ptr)
+@ stdcall SeImpersonateClientEx(ptr ptr)
+@ stdcall SeLockSubjectContext(ptr)
+@ stdcall SeMarkLogonSessionForTerminationNotification(ptr)
+@ stdcall SeOpenObjectAuditAlarm(ptr ptr ptr ptr ptr long long long ptr)
+@ stdcall SeOpenObjectForDeleteAuditAlarm(ptr ptr ptr ptr ptr long long long ptr)
+@ stdcall SePrivilegeCheck(ptr ptr long)
+@ stdcall SePrivilegeObjectAuditAlarm(ptr ptr long ptr long long)
+@ extern SePublicDefaultDacl
+@ stdcall SeQueryAuthenticationIdToken(ptr ptr)
+@ stdcall SeQueryInformationToken(ptr long ptr)
+@ stdcall SeQuerySecurityDescriptorInfo(ptr ptr ptr ptr)
+@ stdcall SeQuerySessionIdToken(ptr ptr)
+@ stdcall SeRegisterLogonSessionTerminatedRoutine(ptr)
+@ stdcall SeReleaseSecurityDescriptor(ptr long long)
+@ stdcall SeReleaseSubjectContext(ptr)
+@ stdcall SeSetAccessStateGenericMapping(ptr ptr)
+;SeSetAuditParameter
+@ stdcall SeSetSecurityDescriptorInfo(ptr ptr ptr ptr long ptr)
+@ stdcall SeSetSecurityDescriptorInfoEx(ptr ptr ptr ptr long long ptr)
+@ stdcall SeSinglePrivilegeCheck(long long long)
+@ extern SeSystemDefaultDacl
+@ stdcall SeTokenImpersonationLevel(ptr)
+@ stdcall SeTokenIsAdmin(ptr)
+@ stdcall SeTokenIsRestricted(ptr)
+@ stdcall SeTokenIsWriteRestricted(ptr)
+@ stdcall SeTokenType(ptr)
+@ stdcall SeUnlockSubjectContext(ptr)
+@ stdcall SeUnregisterLogonSessionTerminatedRoutine(ptr)
+@ stdcall SeValidSecurityDescriptor(long ptr)
+@ stdcall VerSetConditionMask(long long long long)
+@ cdecl VfFailDeviceNode(ptr long long long ptr ptr ptr)
+;VfFailDriver
+@ cdecl VfFailSystemBIOS(long long long ptr ptr ptr)
+@ stdcall VfIsVerificationEnabled(long ptr)
+@ stdcall -arch=i386,arm WRITE_REGISTER_BUFFER_UCHAR(ptr ptr long)
+@ stdcall -arch=i386,arm WRITE_REGISTER_BUFFER_ULONG(ptr ptr long)
+@ stdcall -arch=i386,arm WRITE_REGISTER_BUFFER_USHORT(ptr ptr long)
+@ stdcall -arch=i386,arm WRITE_REGISTER_UCHAR(ptr long)
+@ stdcall -arch=i386,arm WRITE_REGISTER_ULONG(ptr long)
+@ stdcall -arch=i386,arm WRITE_REGISTER_USHORT(ptr long)
+;WmiFlushTrace
+;WmiGetClock
+;WmiQueryTrace
+@ stdcall WmiQueryTraceInformation(long ptr long ptr ptr)
+;WmiStartTrace
+;WmiStopTrace
+;WmiTraceFastEvent
+@ cdecl WmiTraceMessage()
+@ stdcall WmiTraceMessageVa(double long ptr long long)
+;WmiUpdateTrace
+;XIPDispatch
+@ stdcall ZwAccessCheckAndAuditAlarm(ptr ptr ptr ptr ptr long ptr long ptr ptr ptr)
+@ stdcall ZwAddBootEntry(ptr long)
+@ stdcall ZwAddDriverEntry(ptr long)
+@ stdcall ZwAdjustPrivilegesToken(ptr long ptr long ptr ptr)
+@ stdcall ZwAlertThread(ptr)
+@ stdcall ZwAllocateVirtualMemory(ptr ptr long ptr long long)
+@ stdcall ZwAssignProcessToJobObject(ptr ptr)
+@ stdcall ZwCancelIoFile(ptr ptr)
+@ stdcall ZwCancelTimer(ptr ptr)
+@ stdcall ZwClearEvent(ptr)
+@ stdcall ZwClose(ptr)
+@ stdcall ZwCloseObjectAuditAlarm(ptr ptr long)
+@ stdcall ZwConnectPort(ptr ptr ptr ptr ptr ptr ptr ptr)
+@ stdcall ZwCreateDirectoryObject(ptr long ptr)
+@ stdcall ZwCreateEvent(ptr long ptr long long)
+@ stdcall ZwCreateFile(ptr long ptr ptr ptr long long long long ptr long)
+@ stdcall ZwCreateJobObject(ptr long ptr)
+@ stdcall ZwCreateKey(ptr long ptr long ptr long ptr)
+@ stdcall ZwCreateSection(ptr long ptr ptr long long ptr)
+@ stdcall ZwCreateSymbolicLinkObject(ptr long ptr ptr)
+@ stdcall ZwCreateTimer(ptr long ptr long)
+@ stdcall ZwDeleteBootEntry(long)
+@ stdcall ZwDeleteDriverEntry(long)
+@ stdcall ZwDeleteFile(ptr)
+@ stdcall ZwDeleteKey(ptr)
+@ stdcall ZwDeleteValueKey(ptr ptr)
+@ stdcall ZwDeviceIoControlFile(ptr ptr ptr ptr ptr long ptr long ptr long)
+@ stdcall ZwDisplayString(ptr)
+@ stdcall ZwDuplicateObject(ptr ptr ptr ptr long long long)
+@ stdcall ZwDuplicateToken(ptr long ptr long long ptr)
+@ stdcall ZwEnumerateBootEntries(ptr ptr)
+@ stdcall ZwEnumerateDriverEntries(ptr ptr)
+@ stdcall ZwEnumerateKey(ptr long long ptr long ptr)
+@ stdcall ZwEnumerateValueKey(ptr long long ptr long ptr)
+@ stdcall ZwFlushInstructionCache(ptr ptr long)
+@ stdcall ZwFlushKey(ptr)
+@ stdcall ZwFlushVirtualMemory(ptr ptr ptr ptr)
+@ stdcall ZwFreeVirtualMemory(ptr ptr ptr long)
+@ stdcall ZwFsControlFile(ptr ptr ptr ptr ptr long ptr long ptr long)
+@ stdcall ZwInitiatePowerAction(long long long long)
+@ stdcall ZwIsProcessInJob(ptr ptr)
+@ stdcall ZwLoadDriver(ptr)
+@ stdcall ZwLoadKey(ptr ptr)
+@ stdcall ZwMakeTemporaryObject(ptr)
+@ stdcall ZwMapViewOfSection(ptr ptr ptr long long ptr ptr long long long)
+@ stdcall ZwModifyBootEntry(ptr)
+@ stdcall ZwModifyDriverEntry(ptr)
+@ stdcall ZwNotifyChangeKey(ptr ptr ptr ptr ptr long long ptr long long)
+@ stdcall ZwOpenDirectoryObject(ptr long ptr)
+@ stdcall ZwOpenEvent(ptr long ptr)
+@ stdcall ZwOpenFile(ptr long ptr ptr long long)
+@ stdcall ZwOpenJobObject(ptr long ptr)
+@ stdcall ZwOpenKey(ptr long ptr)
+@ stdcall ZwOpenProcess(ptr long ptr ptr)
+@ stdcall ZwOpenProcessToken(ptr long ptr)
+@ stdcall ZwOpenProcessTokenEx(ptr long long ptr)
+@ stdcall ZwOpenSection(ptr long ptr)
+@ stdcall ZwOpenSymbolicLinkObject(ptr long ptr)
+@ stdcall ZwOpenThread(ptr long ptr ptr)
+@ stdcall ZwOpenThreadToken(ptr long long ptr)
+@ stdcall ZwOpenThreadTokenEx(ptr long long long ptr)
+@ stdcall ZwOpenTimer(ptr long ptr)
+@ stdcall ZwPowerInformation(long ptr long ptr long)
+@ stdcall ZwPulseEvent(ptr ptr)
+@ stdcall ZwQueryBootEntryOrder(ptr ptr)
+@ stdcall ZwQueryBootOptions(ptr ptr)
+@ stdcall ZwQueryDefaultLocale(long ptr)
+@ stdcall ZwQueryDefaultUILanguage(ptr)
+@ stdcall ZwQueryDirectoryFile(ptr ptr ptr ptr ptr ptr long long long ptr long)
+@ stdcall ZwQueryDirectoryObject(ptr ptr long long long ptr ptr)
+@ stdcall ZwQueryDriverEntryOrder(ptr ptr)
+@ stdcall ZwQueryEaFile(ptr ptr ptr long long ptr long ptr long)
+@ stdcall ZwQueryFullAttributesFile(ptr ptr)
+@ stdcall ZwQueryInformationAtom(ptr long ptr long ptr)
+@ stdcall ZwQueryInformationFile(ptr ptr ptr long long)
+@ stdcall ZwQueryInformationJobObject(ptr long ptr long ptr)
+@ stdcall ZwQueryInformationProcess(ptr long ptr long ptr)
+@ stdcall ZwQueryInformationThread(ptr long ptr long ptr)
+@ stdcall ZwQueryInformationToken(ptr long long long ptr)
+@ stdcall ZwQueryInstallUILanguage(ptr)
+@ stdcall ZwQueryKey(ptr long ptr long ptr)
+@ stdcall ZwQueryObject(ptr long ptr long ptr)
+@ stdcall ZwQuerySection(ptr long ptr long ptr)
+@ stdcall ZwQuerySecurityObject(ptr long ptr long ptr)
+@ stdcall ZwQuerySymbolicLinkObject(ptr ptr ptr)
+@ stdcall ZwQuerySystemInformation(long ptr long ptr)
+@ stdcall ZwQueryValueKey(ptr ptr long ptr long ptr)
+@ stdcall ZwQueryVolumeInformationFile(ptr ptr ptr long long)
+@ stdcall ZwReadFile(ptr ptr ptr ptr ptr ptr long ptr ptr)
+@ stdcall ZwReplaceKey(ptr ptr ptr)
+@ stdcall ZwRequestWaitReplyPort(ptr ptr ptr)
+@ stdcall ZwResetEvent(ptr ptr)
+@ stdcall ZwRestoreKey(ptr ptr long)
+@ stdcall ZwSaveKey(ptr ptr)
+@ stdcall ZwSaveKeyEx(ptr ptr long)
+@ stdcall ZwSecureConnectPort(ptr ptr ptr ptr ptr ptr ptr ptr ptr)
+@ stdcall ZwSetBootEntryOrder(ptr ptr)
+@ stdcall ZwSetBootOptions(ptr long)
+@ stdcall ZwSetDefaultLocale(long long)
+@ stdcall ZwSetDefaultUILanguage(long)
+@ stdcall ZwSetDriverEntryOrder(ptr ptr)
+@ stdcall ZwSetEaFile(ptr ptr ptr long)
+@ stdcall ZwSetEvent(ptr ptr)
+@ stdcall ZwSetInformationFile(ptr ptr ptr long long)
+@ stdcall ZwSetInformationJobObject(ptr long ptr long)
+@ stdcall ZwSetInformationObject(ptr long ptr long)
+@ stdcall ZwSetInformationProcess(ptr long ptr long)
+@ stdcall ZwSetInformationThread(ptr long ptr long)
+@ stdcall ZwSetSecurityObject(ptr long ptr)
+@ stdcall ZwSetSystemInformation(long ptr long)
+@ stdcall ZwSetSystemTime(ptr ptr)
+@ stdcall ZwSetTimer(ptr ptr ptr ptr long long ptr)
+@ stdcall ZwSetValueKey(ptr ptr long long ptr long)
+@ stdcall ZwSetVolumeInformationFile(ptr ptr ptr long long)
+@ stdcall ZwTerminateJobObject(ptr long)
+@ stdcall ZwTerminateProcess(ptr long)
+@ stdcall ZwTranslateFilePath(ptr long ptr long)
+@ stdcall ZwUnloadDriver(ptr)
+@ stdcall ZwUnloadKey(ptr)
+@ stdcall ZwUnmapViewOfSection(ptr ptr)
+@ stdcall ZwWaitForMultipleObjects(long ptr long long ptr)
+@ stdcall ZwWaitForSingleObject(ptr long ptr)
+@ stdcall ZwWriteFile(ptr ptr ptr ptr ptr ptr long ptr ptr)
+@ stdcall ZwYieldExecution()
+;_CIcos
+;_CIsin
+;_CIsqrt
+@ cdecl -arch=i386,arm _abnormal_termination()
+@ cdecl -arch=i386 _alldiv()
+@ cdecl -arch=i386 _alldvrm()
+@ cdecl -arch=i386 _allmul()
+@ cdecl -arch=i386 _alloca_probe()
+@ cdecl -arch=i386 _allrem()
+@ cdecl -arch=i386 _allshl()
+@ cdecl -arch=i386 _allshr()
+@ cdecl -arch=i386 _aulldiv()
+@ cdecl -arch=i386 _aulldvrm()
+@ cdecl -arch=i386 _aullrem()
+@ cdecl -arch=i386 _aullshr()
+@ cdecl -arch=i386,arm _except_handler2()
+@ cdecl -arch=i386,arm _except_handler3()
+@ cdecl -arch=i386,arm _global_unwind2()
+@ cdecl _itoa()
+@ cdecl _itow()
+@ cdecl -arch=i386,arm _local_unwind2()
+@ cdecl _purecall()
+@ cdecl _snprintf()
+@ cdecl _snwprintf()
+@ cdecl _stricmp()
+@ cdecl _strlwr()
+@ cdecl _strnicmp()
+@ cdecl _strnset()
+@ cdecl _strrev()
+@ cdecl _strset()
+@ cdecl _strupr()
+@ cdecl _vsnprintf()
+@ cdecl _vsnwprintf()
+@ cdecl _wcsicmp()
+@ cdecl _wcslwr()
+@ cdecl _wcsnicmp()
+@ cdecl _wcsnset()
+@ cdecl _wcsrev()
+@ cdecl _wcsupr()
+@ cdecl atoi()
+@ cdecl atol()
+@ cdecl isdigit()
+@ cdecl islower()
+@ cdecl isprint()
+@ cdecl isspace()
+@ cdecl isupper()
+@ cdecl isxdigit()
+@ cdecl mbstowcs()
+@ cdecl mbtowc()
+@ cdecl memchr()
+@ cdecl memcpy()
+@ cdecl memmove()
+@ cdecl memset()
+@ cdecl qsort()
+@ cdecl rand()
+@ cdecl sprintf()
+@ cdecl srand()
+@ cdecl strcat()
+@ cdecl strchr()
+@ cdecl strcmp()
+@ cdecl strcpy()
+@ cdecl strlen()
+@ cdecl strncat()
+@ cdecl strncmp()
+@ cdecl strncpy()
+@ cdecl strrchr()
+@ cdecl strspn()
+@ cdecl strstr()
+@ cdecl swprintf()
+@ cdecl tolower()
+@ cdecl toupper()
+@ cdecl towlower()
+@ cdecl towupper()
+@ stdcall vDbgPrintEx(long long str ptr)
+@ stdcall vDbgPrintExWithPrefix(str long long str ptr)
+@ cdecl vsprintf()
+@ cdecl wcscat()
+@ cdecl wcschr()
+@ cdecl wcscmp()
+@ cdecl wcscpy()
+@ cdecl wcscspn()
+@ cdecl wcslen()
+@ cdecl wcsncat()
+@ cdecl wcsncmp()
+@ cdecl wcsncpy()
+@ cdecl wcsrchr()
+@ cdecl wcsspn()
+@ cdecl wcsstr()
+@ cdecl wcstombs()
+@ cdecl wctomb()