mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-06 10:30:22 +00:00
ntdll: Move the registry system calls to the Unix library.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
1960df8a2a
commit
7053b7c615
|
@ -52,6 +52,7 @@ C_SRCS = \
|
|||
unix/file.c \
|
||||
unix/loader.c \
|
||||
unix/process.c \
|
||||
unix/registry.c \
|
||||
unix/serial.c \
|
||||
unix/server.c \
|
||||
unix/signal_arm.c \
|
||||
|
|
|
@ -166,8 +166,8 @@
|
|||
@ stdcall -syscall NtCreateIoCompletion(ptr long ptr long)
|
||||
@ stdcall -syscall NtCreateJobObject(ptr long ptr)
|
||||
# @ stub NtCreateJobSet
|
||||
@ stdcall NtCreateKey(ptr long ptr long ptr long ptr)
|
||||
@ stdcall NtCreateKeyTransacted(ptr long ptr long ptr long long ptr)
|
||||
@ stdcall -syscall NtCreateKey(ptr long ptr long ptr long ptr)
|
||||
@ stdcall -syscall NtCreateKeyTransacted(ptr long ptr long ptr long long ptr)
|
||||
@ stdcall -syscall NtCreateKeyedEvent(ptr long ptr long)
|
||||
@ stdcall NtCreateLowBoxToken(ptr long long ptr ptr long ptr long ptr)
|
||||
@ stdcall -syscall NtCreateMailslotFile(ptr long ptr ptr long long long ptr)
|
||||
|
@ -195,24 +195,24 @@
|
|||
@ stdcall NtDeleteAtom(long)
|
||||
# @ stub NtDeleteBootEntry
|
||||
@ stdcall -syscall NtDeleteFile(ptr)
|
||||
@ stdcall NtDeleteKey(long)
|
||||
@ stdcall -syscall NtDeleteKey(long)
|
||||
# @ stub NtDeleteObjectAuditAlarm
|
||||
@ stdcall NtDeleteValueKey(long ptr)
|
||||
@ stdcall -syscall NtDeleteValueKey(long ptr)
|
||||
@ stdcall -syscall NtDeviceIoControlFile(long long ptr ptr ptr long ptr long ptr long)
|
||||
@ stdcall NtDisplayString(ptr)
|
||||
@ stdcall -syscall NtDuplicateObject(long long long ptr long long long)
|
||||
@ stdcall NtDuplicateToken(long long ptr long long ptr)
|
||||
# @ stub NtEnumerateBootEntries
|
||||
@ stub NtEnumerateBus
|
||||
@ stdcall NtEnumerateKey(long long long ptr long ptr)
|
||||
@ stdcall -syscall NtEnumerateKey(long long long ptr long ptr)
|
||||
# @ stub NtEnumerateSystemEnvironmentValuesEx
|
||||
@ stdcall NtEnumerateValueKey(long long long ptr long ptr)
|
||||
@ stdcall -syscall NtEnumerateValueKey(long long long ptr long ptr)
|
||||
@ stub NtExtendSection
|
||||
# @ stub NtFilterToken
|
||||
@ stdcall NtFindAtom(ptr long ptr)
|
||||
@ stdcall -syscall NtFlushBuffersFile(long ptr)
|
||||
@ stdcall -syscall NtFlushInstructionCache(long ptr long)
|
||||
@ stdcall NtFlushKey(long)
|
||||
@ stdcall -syscall NtFlushKey(long)
|
||||
@ stdcall -syscall NtFlushProcessWriteBuffers()
|
||||
@ stdcall -syscall NtFlushVirtualMemory(long ptr ptr long)
|
||||
@ stub NtFlushWriteBuffer
|
||||
|
@ -235,8 +235,8 @@
|
|||
# @ stub NtIsSystemResumeAutomatic
|
||||
@ stdcall NtListenPort(ptr ptr)
|
||||
@ stdcall NtLoadDriver(ptr)
|
||||
@ stdcall NtLoadKey2(ptr ptr long)
|
||||
@ stdcall NtLoadKey(ptr ptr)
|
||||
@ stdcall -syscall NtLoadKey2(ptr ptr long)
|
||||
@ stdcall -syscall NtLoadKey(ptr ptr)
|
||||
@ stdcall NtLockFile(long long ptr ptr ptr ptr ptr ptr long long)
|
||||
# @ stub NtLockProductActivationKeys
|
||||
# @ stub NtLockRegistryKey
|
||||
|
@ -248,18 +248,18 @@
|
|||
@ stdcall -syscall NtMapViewOfSection(long long ptr long long ptr ptr long long long)
|
||||
# @ stub NtModifyBootEntry
|
||||
@ stdcall -syscall NtNotifyChangeDirectoryFile(long long ptr ptr ptr ptr long long long)
|
||||
@ stdcall NtNotifyChangeKey(long long ptr ptr ptr long long ptr long long)
|
||||
@ stdcall NtNotifyChangeMultipleKeys(long long ptr long ptr ptr ptr long long ptr long long)
|
||||
@ stdcall -syscall NtNotifyChangeKey(long long ptr ptr ptr long long ptr long long)
|
||||
@ stdcall -syscall NtNotifyChangeMultipleKeys(long long ptr long ptr ptr ptr long long ptr long long)
|
||||
@ stdcall NtOpenDirectoryObject(ptr long ptr)
|
||||
@ stdcall -syscall NtOpenEvent(ptr long ptr)
|
||||
@ stub NtOpenEventPair
|
||||
@ stdcall -syscall NtOpenFile(ptr long ptr ptr long long)
|
||||
@ stdcall -syscall NtOpenIoCompletion(ptr long ptr)
|
||||
@ stdcall -syscall NtOpenJobObject(ptr long ptr)
|
||||
@ stdcall NtOpenKey(ptr long ptr)
|
||||
@ stdcall NtOpenKeyEx(ptr long ptr long)
|
||||
@ stdcall NtOpenKeyTransacted(ptr long ptr long)
|
||||
@ stdcall NtOpenKeyTransactedEx(ptr long ptr long long)
|
||||
@ stdcall -syscall NtOpenKey(ptr long ptr)
|
||||
@ stdcall -syscall NtOpenKeyEx(ptr long ptr long)
|
||||
@ stdcall -syscall NtOpenKeyTransacted(ptr long ptr long)
|
||||
@ stdcall -syscall NtOpenKeyTransactedEx(ptr long ptr long long)
|
||||
@ stdcall -syscall NtOpenKeyedEvent(ptr long ptr)
|
||||
@ stdcall -syscall NtOpenMutant(ptr long ptr)
|
||||
@ stub NtOpenObjectAuditAlarm
|
||||
|
@ -301,9 +301,9 @@
|
|||
@ stdcall NtQueryInstallUILanguage(ptr)
|
||||
@ stub NtQueryIntervalProfile
|
||||
@ stdcall -syscall NtQueryIoCompletion(long long ptr long ptr)
|
||||
@ stdcall NtQueryKey (long long ptr long ptr)
|
||||
@ stdcall NtQueryLicenseValue(ptr ptr ptr long ptr)
|
||||
@ stdcall NtQueryMultipleValueKey(long ptr long ptr long ptr)
|
||||
@ stdcall -syscall NtQueryKey(long long ptr long ptr)
|
||||
@ stdcall -syscall NtQueryLicenseValue(ptr ptr ptr long ptr)
|
||||
@ stdcall -syscall NtQueryMultipleValueKey(long ptr long ptr long ptr)
|
||||
@ stdcall -syscall NtQueryMutant(long long ptr long ptr)
|
||||
@ stdcall -syscall NtQueryObject(long long ptr long ptr)
|
||||
@ stub NtQueryOpenSubKeys
|
||||
|
@ -321,7 +321,7 @@
|
|||
@ stdcall -syscall NtQuerySystemTime(ptr)
|
||||
@ stdcall -syscall NtQueryTimer(ptr long ptr long ptr)
|
||||
@ stdcall NtQueryTimerResolution(ptr ptr ptr)
|
||||
@ stdcall NtQueryValueKey(long ptr long ptr long ptr)
|
||||
@ stdcall -syscall NtQueryValueKey(long ptr long ptr long ptr)
|
||||
@ stdcall -syscall NtQueryVirtualMemory(long ptr long ptr long ptr)
|
||||
@ stdcall -syscall NtQueryVolumeInformationFile(long ptr ptr long long)
|
||||
@ stdcall -syscall NtQueueApcThread(long ptr long long long)
|
||||
|
@ -340,8 +340,8 @@
|
|||
@ stdcall -syscall NtRemoveIoCompletion(ptr ptr ptr ptr ptr)
|
||||
@ stdcall -syscall NtRemoveIoCompletionEx(ptr ptr long ptr ptr long)
|
||||
# @ stub NtRemoveProcessDebug
|
||||
@ stdcall NtRenameKey(long ptr)
|
||||
@ stdcall NtReplaceKey(ptr long ptr)
|
||||
@ stdcall -syscall NtRenameKey(long ptr)
|
||||
@ stdcall -syscall NtReplaceKey(ptr long ptr)
|
||||
@ stub NtReplyPort
|
||||
@ stdcall NtReplyWaitReceivePort(ptr ptr ptr ptr)
|
||||
@ stub NtReplyWaitReceivePortEx
|
||||
|
@ -352,10 +352,10 @@
|
|||
# @ stub NtRequestWakeupLatency
|
||||
@ stdcall -syscall NtResetEvent(long ptr)
|
||||
@ stdcall -syscall NtResetWriteWatch(long ptr long)
|
||||
@ stdcall NtRestoreKey(long long long)
|
||||
@ stdcall -syscall NtRestoreKey(long long long)
|
||||
@ stdcall -syscall NtResumeProcess(long)
|
||||
@ stdcall -syscall NtResumeThread(long ptr)
|
||||
@ stdcall NtSaveKey(long long)
|
||||
@ stdcall -syscall NtSaveKey(long long)
|
||||
# @ stub NtSaveKeyEx
|
||||
# @ stub NtSaveMergedKeys
|
||||
@ stdcall NtSecureConnectPort(ptr ptr ptr ptr ptr ptr ptr ptr ptr)
|
||||
|
@ -375,7 +375,7 @@
|
|||
# @ stub NtSetInformationDebugObject
|
||||
@ stdcall -syscall NtSetInformationFile(long ptr ptr long long)
|
||||
@ stdcall -syscall NtSetInformationJobObject(long long ptr long)
|
||||
@ stdcall NtSetInformationKey(long long ptr long)
|
||||
@ stdcall -syscall NtSetInformationKey(long long ptr long)
|
||||
@ stdcall -syscall NtSetInformationObject(long long ptr long)
|
||||
@ stdcall -syscall NtSetInformationProcess(long long ptr long)
|
||||
@ stdcall -syscall NtSetInformationThread(long long ptr long)
|
||||
|
@ -398,7 +398,7 @@
|
|||
@ stdcall -syscall NtSetTimer(long ptr ptr ptr long long ptr)
|
||||
@ stdcall NtSetTimerResolution(long long ptr)
|
||||
# @ stub NtSetUuidSeed
|
||||
@ stdcall NtSetValueKey(long ptr long long ptr long)
|
||||
@ stdcall -syscall NtSetValueKey(long ptr long long ptr long)
|
||||
@ stdcall -syscall NtSetVolumeInformationFile(long ptr ptr long long)
|
||||
@ stdcall NtShutdownSystem(long)
|
||||
@ stdcall -syscall NtSignalAndWaitForSingleObject(long long long ptr)
|
||||
|
@ -414,7 +414,7 @@
|
|||
# @ stub NtTraceEvent
|
||||
# @ stub NtTranslateFilePath
|
||||
@ stdcall NtUnloadDriver(ptr)
|
||||
@ stdcall NtUnloadKey(ptr)
|
||||
@ stdcall -syscall NtUnloadKey(ptr)
|
||||
@ stub NtUnloadKeyEx
|
||||
@ stdcall NtUnlockFile(long ptr ptr ptr ptr)
|
||||
@ stdcall -syscall NtUnlockVirtualMemory(long ptr ptr long)
|
||||
|
@ -1155,8 +1155,8 @@
|
|||
@ stdcall -private -syscall ZwCreateIoCompletion(ptr long ptr long) NtCreateIoCompletion
|
||||
@ stdcall -private -syscall ZwCreateJobObject(ptr long ptr) NtCreateJobObject
|
||||
# @ stub ZwCreateJobSet
|
||||
@ stdcall -private ZwCreateKey(ptr long ptr long ptr long ptr) NtCreateKey
|
||||
@ stdcall -private ZwCreateKeyTransacted(ptr long ptr long ptr long long ptr) NtCreateKeyTransacted
|
||||
@ stdcall -private -syscall ZwCreateKey(ptr long ptr long ptr long ptr) NtCreateKey
|
||||
@ stdcall -private -syscall ZwCreateKeyTransacted(ptr long ptr long ptr long long ptr) NtCreateKeyTransacted
|
||||
@ stdcall -private -syscall ZwCreateKeyedEvent(ptr long ptr long) NtCreateKeyedEvent
|
||||
@ stdcall -private -syscall ZwCreateMailslotFile(ptr long ptr ptr long long long ptr) NtCreateMailslotFile
|
||||
@ stdcall -private -syscall ZwCreateMutant(ptr long ptr long) NtCreateMutant
|
||||
|
@ -1182,24 +1182,24 @@
|
|||
@ stdcall -private ZwDeleteAtom(long) NtDeleteAtom
|
||||
# @ stub ZwDeleteBootEntry
|
||||
@ stdcall -private -syscall ZwDeleteFile(ptr) NtDeleteFile
|
||||
@ stdcall -private ZwDeleteKey(long) NtDeleteKey
|
||||
@ stdcall -private -syscall ZwDeleteKey(long) NtDeleteKey
|
||||
# @ stub ZwDeleteObjectAuditAlarm
|
||||
@ stdcall -private ZwDeleteValueKey(long ptr) NtDeleteValueKey
|
||||
@ stdcall -private -syscall ZwDeleteValueKey(long ptr) NtDeleteValueKey
|
||||
@ stdcall -private -syscall ZwDeviceIoControlFile(long long ptr ptr ptr long ptr long ptr long) NtDeviceIoControlFile
|
||||
@ stdcall -private ZwDisplayString(ptr) NtDisplayString
|
||||
@ stdcall -private -syscall ZwDuplicateObject(long long long ptr long long long) NtDuplicateObject
|
||||
@ stdcall -private ZwDuplicateToken(long long ptr long long ptr) NtDuplicateToken
|
||||
# @ stub ZwEnumerateBootEntries
|
||||
@ stub ZwEnumerateBus
|
||||
@ stdcall -private ZwEnumerateKey(long long long ptr long ptr) NtEnumerateKey
|
||||
@ stdcall -private -syscall ZwEnumerateKey(long long long ptr long ptr) NtEnumerateKey
|
||||
# @ stub ZwEnumerateSystemEnvironmentValuesEx
|
||||
@ stdcall -private ZwEnumerateValueKey(long long long ptr long ptr) NtEnumerateValueKey
|
||||
@ stdcall -private -syscall ZwEnumerateValueKey(long long long ptr long ptr) NtEnumerateValueKey
|
||||
@ stub ZwExtendSection
|
||||
# @ stub ZwFilterToken
|
||||
@ stdcall -private ZwFindAtom(ptr long ptr) NtFindAtom
|
||||
@ stdcall -private -syscall ZwFlushBuffersFile(long ptr) NtFlushBuffersFile
|
||||
@ stdcall -private -syscall ZwFlushInstructionCache(long ptr long) NtFlushInstructionCache
|
||||
@ stdcall -private ZwFlushKey(long) NtFlushKey
|
||||
@ stdcall -private -syscall ZwFlushKey(long) NtFlushKey
|
||||
@ stdcall -private -syscall ZwFlushProcessWriteBuffers() NtFlushProcessWriteBuffers
|
||||
@ stdcall -private -syscall ZwFlushVirtualMemory(long ptr ptr long) NtFlushVirtualMemory
|
||||
@ stub ZwFlushWriteBuffer
|
||||
|
@ -1222,8 +1222,8 @@
|
|||
# @ stub ZwIsSystemResumeAutomatic
|
||||
@ stdcall -private ZwListenPort(ptr ptr) NtListenPort
|
||||
@ stdcall -private ZwLoadDriver(ptr) NtLoadDriver
|
||||
@ stdcall -private ZwLoadKey2(ptr ptr long) NtLoadKey2
|
||||
@ stdcall -private ZwLoadKey(ptr ptr) NtLoadKey
|
||||
@ stdcall -private -syscall ZwLoadKey2(ptr ptr long) NtLoadKey2
|
||||
@ stdcall -private -syscall ZwLoadKey(ptr ptr) NtLoadKey
|
||||
@ stdcall -private ZwLockFile(long long ptr ptr ptr ptr ptr ptr long long) NtLockFile
|
||||
# @ stub ZwLockProductActivationKeys
|
||||
# @ stub ZwLockRegistryKey
|
||||
|
@ -1235,18 +1235,18 @@
|
|||
@ stdcall -private -syscall ZwMapViewOfSection(long long ptr long long ptr ptr long long long) NtMapViewOfSection
|
||||
# @ stub ZwModifyBootEntry
|
||||
@ stdcall -private -syscall ZwNotifyChangeDirectoryFile(long long ptr ptr ptr ptr long long long) NtNotifyChangeDirectoryFile
|
||||
@ stdcall -private ZwNotifyChangeKey(long long ptr ptr ptr long long ptr long long) NtNotifyChangeKey
|
||||
@ stdcall -private ZwNotifyChangeMultipleKeys(long long ptr long ptr ptr ptr long long ptr long long) NtNotifyChangeMultipleKeys
|
||||
@ stdcall -private -syscall ZwNotifyChangeKey(long long ptr ptr ptr long long ptr long long) NtNotifyChangeKey
|
||||
@ stdcall -private -syscall ZwNotifyChangeMultipleKeys(long long ptr long ptr ptr ptr long long ptr long long) NtNotifyChangeMultipleKeys
|
||||
@ stdcall -private ZwOpenDirectoryObject(ptr long ptr) NtOpenDirectoryObject
|
||||
@ stdcall -private -syscall ZwOpenEvent(ptr long ptr) NtOpenEvent
|
||||
@ stub ZwOpenEventPair
|
||||
@ stdcall -private -syscall ZwOpenFile(ptr long ptr ptr long long) NtOpenFile
|
||||
@ stdcall -private -syscall ZwOpenIoCompletion(ptr long ptr) NtOpenIoCompletion
|
||||
@ stdcall -private -syscall ZwOpenJobObject(ptr long ptr) NtOpenJobObject
|
||||
@ stdcall -private ZwOpenKey(ptr long ptr) NtOpenKey
|
||||
@ stdcall -private ZwOpenKeyEx(ptr long ptr long) NtOpenKeyEx
|
||||
@ stdcall -private ZwOpenKeyTransacted(ptr long ptr long) NtOpenKeyTransacted
|
||||
@ stdcall -private ZwOpenKeyTransactedEx(ptr long ptr long long) NtOpenKeyTransactedEx
|
||||
@ stdcall -private -syscall ZwOpenKey(ptr long ptr) NtOpenKey
|
||||
@ stdcall -private -syscall ZwOpenKeyEx(ptr long ptr long) NtOpenKeyEx
|
||||
@ stdcall -private -syscall ZwOpenKeyTransacted(ptr long ptr long) NtOpenKeyTransacted
|
||||
@ stdcall -private -syscall ZwOpenKeyTransactedEx(ptr long ptr long long) NtOpenKeyTransactedEx
|
||||
@ stdcall -private -syscall ZwOpenKeyedEvent(ptr long ptr) NtOpenKeyedEvent
|
||||
@ stdcall -private -syscall ZwOpenMutant(ptr long ptr) NtOpenMutant
|
||||
@ stub ZwOpenObjectAuditAlarm
|
||||
|
@ -1288,9 +1288,9 @@
|
|||
@ stdcall -private ZwQueryInstallUILanguage(ptr) NtQueryInstallUILanguage
|
||||
@ stub ZwQueryIntervalProfile
|
||||
@ stdcall -private -syscall ZwQueryIoCompletion(long long ptr long ptr) NtQueryIoCompletion
|
||||
@ stdcall -private ZwQueryKey(long long ptr long ptr) NtQueryKey
|
||||
@ stdcall -private ZwQueryLicenseValue(ptr ptr ptr long ptr) NtQueryLicenseValue
|
||||
@ stdcall -private ZwQueryMultipleValueKey(long ptr long ptr long ptr) NtQueryMultipleValueKey
|
||||
@ stdcall -private -syscall ZwQueryKey(long long ptr long ptr) NtQueryKey
|
||||
@ stdcall -private -syscall ZwQueryLicenseValue(ptr ptr ptr long ptr) NtQueryLicenseValue
|
||||
@ stdcall -private -syscall ZwQueryMultipleValueKey(long ptr long ptr long ptr) NtQueryMultipleValueKey
|
||||
@ stdcall -private -syscall ZwQueryMutant(long long ptr long ptr) NtQueryMutant
|
||||
@ stdcall -private -syscall ZwQueryObject(long long ptr long ptr) NtQueryObject
|
||||
@ stub ZwQueryOpenSubKeys
|
||||
|
@ -1308,7 +1308,7 @@
|
|||
@ stdcall -private -syscall ZwQuerySystemTime(ptr) NtQuerySystemTime
|
||||
@ stdcall -private -syscall ZwQueryTimer(ptr long ptr long ptr) NtQueryTimer
|
||||
@ stdcall -private ZwQueryTimerResolution(ptr ptr ptr) NtQueryTimerResolution
|
||||
@ stdcall -private ZwQueryValueKey(long ptr long ptr long ptr) NtQueryValueKey
|
||||
@ stdcall -private -syscall ZwQueryValueKey(long ptr long ptr long ptr) NtQueryValueKey
|
||||
@ stdcall -private -syscall ZwQueryVirtualMemory(long ptr long ptr long ptr) NtQueryVirtualMemory
|
||||
@ stdcall -private -syscall ZwQueryVolumeInformationFile(long ptr ptr long long) NtQueryVolumeInformationFile
|
||||
@ stdcall -private -syscall ZwQueueApcThread(long ptr long long long) NtQueueApcThread
|
||||
|
@ -1327,8 +1327,8 @@
|
|||
@ stdcall -private -syscall ZwRemoveIoCompletion(ptr ptr ptr ptr ptr) NtRemoveIoCompletion
|
||||
@ stdcall -private -syscall ZwRemoveIoCompletionEx(ptr ptr long ptr ptr long) NtRemoveIoCompletionEx
|
||||
# @ stub ZwRemoveProcessDebug
|
||||
@ stdcall -private ZwRenameKey(long ptr) NtRenameKey
|
||||
@ stdcall -private ZwReplaceKey(ptr long ptr) NtReplaceKey
|
||||
@ stdcall -private -syscall ZwRenameKey(long ptr) NtRenameKey
|
||||
@ stdcall -private -syscall ZwReplaceKey(ptr long ptr) NtReplaceKey
|
||||
@ stub ZwReplyPort
|
||||
@ stdcall -private ZwReplyWaitReceivePort(ptr ptr ptr ptr) NtReplyWaitReceivePort
|
||||
@ stub ZwReplyWaitReceivePortEx
|
||||
|
@ -1339,10 +1339,10 @@
|
|||
# @ stub ZwRequestWakeupLatency
|
||||
@ stdcall -private -syscall ZwResetEvent(long ptr) NtResetEvent
|
||||
@ stdcall -private -syscall ZwResetWriteWatch(long ptr long) NtResetWriteWatch
|
||||
@ stdcall -private ZwRestoreKey(long long long) NtRestoreKey
|
||||
@ stdcall -private -syscall ZwRestoreKey(long long long) NtRestoreKey
|
||||
@ stdcall -private -syscall ZwResumeProcess(long) NtResumeProcess
|
||||
@ stdcall -private -syscall ZwResumeThread(long ptr) NtResumeThread
|
||||
@ stdcall -private ZwSaveKey(long long) NtSaveKey
|
||||
@ stdcall -private -syscall ZwSaveKey(long long) NtSaveKey
|
||||
# @ stub ZwSaveKeyEx
|
||||
# @ stub ZwSaveMergedKeys
|
||||
@ stdcall -private ZwSecureConnectPort(ptr ptr ptr ptr ptr ptr ptr ptr ptr) NtSecureConnectPort
|
||||
|
@ -1362,7 +1362,7 @@
|
|||
# @ stub ZwSetInformationDebugObject
|
||||
@ stdcall -private -syscall ZwSetInformationFile(long ptr ptr long long) NtSetInformationFile
|
||||
@ stdcall -private -syscall ZwSetInformationJobObject(long long ptr long) NtSetInformationJobObject
|
||||
@ stdcall -private ZwSetInformationKey(long long ptr long) NtSetInformationKey
|
||||
@ stdcall -private -syscall ZwSetInformationKey(long long ptr long) NtSetInformationKey
|
||||
@ stdcall -private -syscall ZwSetInformationObject(long long ptr long) NtSetInformationObject
|
||||
@ stdcall -private -syscall ZwSetInformationProcess(long long ptr long) NtSetInformationProcess
|
||||
@ stdcall -private -syscall ZwSetInformationThread(long long ptr long) NtSetInformationThread
|
||||
|
@ -1385,7 +1385,7 @@
|
|||
@ stdcall -private -syscall ZwSetTimer(long ptr ptr ptr long long ptr) NtSetTimer
|
||||
@ stdcall -private ZwSetTimerResolution(long long ptr) NtSetTimerResolution
|
||||
# @ stub ZwSetUuidSeed
|
||||
@ stdcall -private ZwSetValueKey(long ptr long long ptr long) NtSetValueKey
|
||||
@ stdcall -private -syscall ZwSetValueKey(long ptr long long ptr long) NtSetValueKey
|
||||
@ stdcall -private -syscall ZwSetVolumeInformationFile(long ptr ptr long long) NtSetVolumeInformationFile
|
||||
@ stdcall -private ZwShutdownSystem(long) NtShutdownSystem
|
||||
@ stdcall -private -syscall ZwSignalAndWaitForSingleObject(long long long ptr) NtSignalAndWaitForSingleObject
|
||||
|
@ -1401,7 +1401,7 @@
|
|||
# @ stub ZwTraceEvent
|
||||
# @ stub ZwTranslateFilePath
|
||||
@ stdcall -private ZwUnloadDriver(ptr) NtUnloadDriver
|
||||
@ stdcall -private ZwUnloadKey(ptr) NtUnloadKey
|
||||
@ stdcall -private -syscall ZwUnloadKey(ptr) NtUnloadKey
|
||||
@ stub ZwUnloadKeyEx
|
||||
@ stdcall -private ZwUnlockFile(long ptr ptr ptr ptr) NtUnlockFile
|
||||
@ stdcall -private -syscall ZwUnlockVirtualMemory(long ptr ptr long) NtUnlockVirtualMemory
|
||||
|
|
795
dlls/ntdll/reg.c
795
dlls/ntdll/reg.c
|
@ -37,60 +37,6 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(reg);
|
||||
|
||||
/* maximum length of a value name in bytes (without terminating null) */
|
||||
#define MAX_VALUE_LENGTH (16383 * sizeof(WCHAR))
|
||||
|
||||
/******************************************************************************
|
||||
* NtCreateKey [NTDLL.@]
|
||||
* ZwCreateKey [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI NtCreateKey( PHANDLE retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr,
|
||||
ULONG TitleIndex, const UNICODE_STRING *class, ULONG options,
|
||||
PULONG dispos )
|
||||
{
|
||||
NTSTATUS ret;
|
||||
data_size_t len;
|
||||
struct object_attributes *objattr;
|
||||
|
||||
if (!retkey || !attr) return STATUS_ACCESS_VIOLATION;
|
||||
if (attr->Length > sizeof(OBJECT_ATTRIBUTES)) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
TRACE( "(%p,%s,%s,%x,%x,%p)\n", attr->RootDirectory, debugstr_us(attr->ObjectName),
|
||||
debugstr_us(class), options, access, retkey );
|
||||
|
||||
if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret;
|
||||
|
||||
SERVER_START_REQ( create_key )
|
||||
{
|
||||
req->access = access;
|
||||
req->options = options;
|
||||
wine_server_add_data( req, objattr, len );
|
||||
if (class) wine_server_add_data( req, class->Buffer, class->Length );
|
||||
ret = wine_server_call( req );
|
||||
*retkey = wine_server_ptr_handle( reply->hkey );
|
||||
if (dispos && !ret) *dispos = reply->created ? REG_CREATED_NEW_KEY : REG_OPENED_EXISTING_KEY;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
TRACE("<- %p\n", *retkey);
|
||||
RtlFreeHeap( GetProcessHeap(), 0, objattr );
|
||||
return ret;
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI NtCreateKeyTransacted( PHANDLE retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr,
|
||||
ULONG TitleIndex, const UNICODE_STRING *class, ULONG options,
|
||||
HANDLE transacted, ULONG *dispos )
|
||||
{
|
||||
FIXME( "(%p,%s,%s,%x,%x,%p,%p)\n", attr->RootDirectory, debugstr_us(attr->ObjectName),
|
||||
debugstr_us(class), options, access, transacted, retkey );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI NtRenameKey( HANDLE handle, UNICODE_STRING *name )
|
||||
{
|
||||
FIXME( "(%p %s)\n", handle, debugstr_us(name) );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* RtlpNtCreateKey [NTDLL.@]
|
||||
|
@ -113,67 +59,6 @@ NTSTATUS WINAPI RtlpNtCreateKey( PHANDLE retkey, ACCESS_MASK access, const OBJEC
|
|||
return NtCreateKey(retkey, access, attr, 0, NULL, 0, dispos);
|
||||
}
|
||||
|
||||
static NTSTATUS open_key( PHANDLE retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr, ULONG options )
|
||||
{
|
||||
NTSTATUS ret;
|
||||
|
||||
if (!retkey || !attr || !attr->ObjectName) return STATUS_ACCESS_VIOLATION;
|
||||
if ((ret = validate_open_object_attributes( attr ))) return ret;
|
||||
|
||||
TRACE( "(%p,%s,%x,%p)\n", attr->RootDirectory,
|
||||
debugstr_us(attr->ObjectName), access, retkey );
|
||||
if (options & ~REG_OPTION_OPEN_LINK)
|
||||
FIXME("options %x not implemented\n", options);
|
||||
|
||||
SERVER_START_REQ( open_key )
|
||||
{
|
||||
req->parent = wine_server_obj_handle( attr->RootDirectory );
|
||||
req->access = access;
|
||||
req->attributes = attr->Attributes;
|
||||
wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length );
|
||||
ret = wine_server_call( req );
|
||||
*retkey = wine_server_ptr_handle( reply->hkey );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
TRACE("<- %p\n", *retkey);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* NtOpenKeyEx [NTDLL.@]
|
||||
* ZwOpenKeyEx [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI NtOpenKeyEx( PHANDLE retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr, ULONG options )
|
||||
{
|
||||
return open_key( retkey, access, attr, options );
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* NtOpenKey [NTDLL.@]
|
||||
* ZwOpenKey [NTDLL.@]
|
||||
*
|
||||
* OUT HANDLE retkey (returns 0 when failure)
|
||||
* IN ACCESS_MASK access
|
||||
* IN POBJECT_ATTRIBUTES attr
|
||||
*/
|
||||
NTSTATUS WINAPI NtOpenKey( PHANDLE retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr )
|
||||
{
|
||||
return open_key( retkey, access, attr, 0 );
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI NtOpenKeyTransactedEx( PHANDLE retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr,
|
||||
ULONG options, HANDLE transaction )
|
||||
{
|
||||
FIXME( "(%p %x %p %x %p)\n", retkey, access, attr, options, transaction );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NTSTATUS WINAPI NtOpenKeyTransacted( PHANDLE retkey, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr,
|
||||
HANDLE transaction )
|
||||
{
|
||||
return NtOpenKeyTransactedEx( retkey, access, attr, 0, transaction );
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* RtlpNtOpenKey [NTDLL.@]
|
||||
*
|
||||
|
@ -186,25 +71,6 @@ NTSTATUS WINAPI RtlpNtOpenKey( PHANDLE retkey, ACCESS_MASK access, OBJECT_ATTRIB
|
|||
return NtOpenKey(retkey, access, attr);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* NtDeleteKey [NTDLL.@]
|
||||
* ZwDeleteKey [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI NtDeleteKey( HANDLE hkey )
|
||||
{
|
||||
NTSTATUS ret;
|
||||
|
||||
TRACE( "(%p)\n", hkey );
|
||||
|
||||
SERVER_START_REQ( delete_key )
|
||||
{
|
||||
req->hkey = wine_server_obj_handle( hkey );
|
||||
ret = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* RtlpNtMakeTemporaryKey [NTDLL.@]
|
||||
*
|
||||
|
@ -215,163 +81,6 @@ NTSTATUS WINAPI RtlpNtMakeTemporaryKey( HANDLE hkey )
|
|||
return NtDeleteKey(hkey);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* NtDeleteValueKey [NTDLL.@]
|
||||
* ZwDeleteValueKey [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI NtDeleteValueKey( HANDLE hkey, const UNICODE_STRING *name )
|
||||
{
|
||||
NTSTATUS ret;
|
||||
|
||||
TRACE( "(%p,%s)\n", hkey, debugstr_us(name) );
|
||||
if (name->Length > MAX_VALUE_LENGTH) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
SERVER_START_REQ( delete_key_value )
|
||||
{
|
||||
req->hkey = wine_server_obj_handle( hkey );
|
||||
wine_server_add_data( req, name->Buffer, name->Length );
|
||||
ret = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* enumerate_key
|
||||
*
|
||||
* Implementation of NtQueryKey and NtEnumerateKey
|
||||
*/
|
||||
static NTSTATUS enumerate_key( HANDLE handle, int index, KEY_INFORMATION_CLASS info_class,
|
||||
void *info, DWORD length, DWORD *result_len )
|
||||
|
||||
{
|
||||
NTSTATUS ret;
|
||||
void *data_ptr;
|
||||
size_t fixed_size;
|
||||
|
||||
switch(info_class)
|
||||
{
|
||||
case KeyBasicInformation: data_ptr = ((KEY_BASIC_INFORMATION *)info)->Name; break;
|
||||
case KeyFullInformation: data_ptr = ((KEY_FULL_INFORMATION *)info)->Class; break;
|
||||
case KeyNodeInformation: data_ptr = ((KEY_NODE_INFORMATION *)info)->Name; break;
|
||||
case KeyNameInformation: data_ptr = ((KEY_NAME_INFORMATION *)info)->Name; break;
|
||||
case KeyCachedInformation: data_ptr = ((KEY_CACHED_INFORMATION *)info)+1; break;
|
||||
default:
|
||||
FIXME( "Information class %d not implemented\n", info_class );
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
fixed_size = (char *)data_ptr - (char *)info;
|
||||
|
||||
SERVER_START_REQ( enum_key )
|
||||
{
|
||||
req->hkey = wine_server_obj_handle( handle );
|
||||
req->index = index;
|
||||
req->info_class = info_class;
|
||||
if (length > fixed_size) wine_server_set_reply( req, data_ptr, length - fixed_size );
|
||||
if (!(ret = wine_server_call( req )))
|
||||
{
|
||||
switch(info_class)
|
||||
{
|
||||
case KeyBasicInformation:
|
||||
{
|
||||
KEY_BASIC_INFORMATION keyinfo;
|
||||
fixed_size = (char *)keyinfo.Name - (char *)&keyinfo;
|
||||
keyinfo.LastWriteTime.QuadPart = reply->modif;
|
||||
keyinfo.TitleIndex = 0;
|
||||
keyinfo.NameLength = reply->namelen;
|
||||
memcpy( info, &keyinfo, min( length, fixed_size ) );
|
||||
}
|
||||
break;
|
||||
case KeyFullInformation:
|
||||
{
|
||||
KEY_FULL_INFORMATION keyinfo;
|
||||
fixed_size = (char *)keyinfo.Class - (char *)&keyinfo;
|
||||
keyinfo.LastWriteTime.QuadPart = reply->modif;
|
||||
keyinfo.TitleIndex = 0;
|
||||
keyinfo.ClassLength = wine_server_reply_size(reply);
|
||||
keyinfo.ClassOffset = keyinfo.ClassLength ? fixed_size : -1;
|
||||
keyinfo.SubKeys = reply->subkeys;
|
||||
keyinfo.MaxNameLen = reply->max_subkey;
|
||||
keyinfo.MaxClassLen = reply->max_class;
|
||||
keyinfo.Values = reply->values;
|
||||
keyinfo.MaxValueNameLen = reply->max_value;
|
||||
keyinfo.MaxValueDataLen = reply->max_data;
|
||||
memcpy( info, &keyinfo, min( length, fixed_size ) );
|
||||
}
|
||||
break;
|
||||
case KeyNodeInformation:
|
||||
{
|
||||
KEY_NODE_INFORMATION keyinfo;
|
||||
fixed_size = (char *)keyinfo.Name - (char *)&keyinfo;
|
||||
keyinfo.LastWriteTime.QuadPart = reply->modif;
|
||||
keyinfo.TitleIndex = 0;
|
||||
if (reply->namelen < wine_server_reply_size(reply))
|
||||
{
|
||||
keyinfo.ClassLength = wine_server_reply_size(reply) - reply->namelen;
|
||||
keyinfo.ClassOffset = fixed_size + reply->namelen;
|
||||
}
|
||||
else
|
||||
{
|
||||
keyinfo.ClassLength = 0;
|
||||
keyinfo.ClassOffset = -1;
|
||||
}
|
||||
keyinfo.NameLength = reply->namelen;
|
||||
memcpy( info, &keyinfo, min( length, fixed_size ) );
|
||||
}
|
||||
break;
|
||||
case KeyNameInformation:
|
||||
{
|
||||
KEY_NAME_INFORMATION keyinfo;
|
||||
fixed_size = (char *)keyinfo.Name - (char *)&keyinfo;
|
||||
keyinfo.NameLength = reply->namelen;
|
||||
memcpy( info, &keyinfo, min( length, fixed_size ) );
|
||||
}
|
||||
break;
|
||||
case KeyCachedInformation:
|
||||
{
|
||||
KEY_CACHED_INFORMATION keyinfo;
|
||||
fixed_size = sizeof(keyinfo);
|
||||
keyinfo.LastWriteTime.QuadPart = reply->modif;
|
||||
keyinfo.TitleIndex = 0;
|
||||
keyinfo.SubKeys = reply->subkeys;
|
||||
keyinfo.MaxNameLen = reply->max_subkey;
|
||||
keyinfo.Values = reply->values;
|
||||
keyinfo.MaxValueNameLen = reply->max_value;
|
||||
keyinfo.MaxValueDataLen = reply->max_data;
|
||||
keyinfo.NameLength = reply->namelen;
|
||||
memcpy( info, &keyinfo, min( length, fixed_size ) );
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
*result_len = fixed_size + reply->total;
|
||||
if (length < *result_len) ret = STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtEnumerateKey [NTDLL.@]
|
||||
* ZwEnumerateKey [NTDLL.@]
|
||||
*
|
||||
* NOTES
|
||||
* the name copied into the buffer is NOT 0-terminated
|
||||
*/
|
||||
NTSTATUS WINAPI NtEnumerateKey( HANDLE handle, ULONG index, KEY_INFORMATION_CLASS info_class,
|
||||
void *info, DWORD length, DWORD *result_len )
|
||||
{
|
||||
/* -1 means query key, so avoid it here */
|
||||
if (index == (ULONG)-1) return STATUS_NO_MORE_ENTRIES;
|
||||
return enumerate_key( handle, index, info_class, info, length, result_len );
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* RtlpNtEnumerateSubKey [NTDLL.@]
|
||||
*
|
||||
|
@ -418,175 +127,6 @@ NTSTATUS WINAPI RtlpNtEnumerateSubKey( HANDLE handle, UNICODE_STRING *out, ULONG
|
|||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* NtQueryKey [NTDLL.@]
|
||||
* ZwQueryKey [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI NtQueryKey( HANDLE handle, KEY_INFORMATION_CLASS info_class,
|
||||
void *info, DWORD length, DWORD *result_len )
|
||||
{
|
||||
return enumerate_key( handle, -1, info_class, info, length, result_len );
|
||||
}
|
||||
|
||||
|
||||
/* fill the key value info structure for a specific info class */
|
||||
static void copy_key_value_info( KEY_VALUE_INFORMATION_CLASS info_class, void *info,
|
||||
DWORD length, int type, int name_len, int data_len )
|
||||
{
|
||||
switch(info_class)
|
||||
{
|
||||
case KeyValueBasicInformation:
|
||||
{
|
||||
KEY_VALUE_BASIC_INFORMATION keyinfo;
|
||||
keyinfo.TitleIndex = 0;
|
||||
keyinfo.Type = type;
|
||||
keyinfo.NameLength = name_len;
|
||||
length = min( length, (char *)keyinfo.Name - (char *)&keyinfo );
|
||||
memcpy( info, &keyinfo, length );
|
||||
break;
|
||||
}
|
||||
case KeyValueFullInformation:
|
||||
{
|
||||
KEY_VALUE_FULL_INFORMATION keyinfo;
|
||||
keyinfo.TitleIndex = 0;
|
||||
keyinfo.Type = type;
|
||||
keyinfo.DataOffset = (char *)keyinfo.Name - (char *)&keyinfo + name_len;
|
||||
keyinfo.DataLength = data_len;
|
||||
keyinfo.NameLength = name_len;
|
||||
length = min( length, (char *)keyinfo.Name - (char *)&keyinfo );
|
||||
memcpy( info, &keyinfo, length );
|
||||
break;
|
||||
}
|
||||
case KeyValuePartialInformation:
|
||||
{
|
||||
KEY_VALUE_PARTIAL_INFORMATION keyinfo;
|
||||
keyinfo.TitleIndex = 0;
|
||||
keyinfo.Type = type;
|
||||
keyinfo.DataLength = data_len;
|
||||
length = min( length, (char *)keyinfo.Data - (char *)&keyinfo );
|
||||
memcpy( info, &keyinfo, length );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtEnumerateValueKey [NTDLL.@]
|
||||
* ZwEnumerateValueKey [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI NtEnumerateValueKey( HANDLE handle, ULONG index,
|
||||
KEY_VALUE_INFORMATION_CLASS info_class,
|
||||
void *info, DWORD length, DWORD *result_len )
|
||||
{
|
||||
NTSTATUS ret;
|
||||
void *ptr;
|
||||
size_t fixed_size;
|
||||
|
||||
TRACE( "(%p,%u,%d,%p,%d)\n", handle, index, info_class, info, length );
|
||||
|
||||
/* compute the length we want to retrieve */
|
||||
switch(info_class)
|
||||
{
|
||||
case KeyValueBasicInformation: ptr = ((KEY_VALUE_BASIC_INFORMATION *)info)->Name; break;
|
||||
case KeyValueFullInformation: ptr = ((KEY_VALUE_FULL_INFORMATION *)info)->Name; break;
|
||||
case KeyValuePartialInformation: ptr = ((KEY_VALUE_PARTIAL_INFORMATION *)info)->Data; break;
|
||||
default:
|
||||
FIXME( "Information class %d not implemented\n", info_class );
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
fixed_size = (char *)ptr - (char *)info;
|
||||
|
||||
SERVER_START_REQ( enum_key_value )
|
||||
{
|
||||
req->hkey = wine_server_obj_handle( handle );
|
||||
req->index = index;
|
||||
req->info_class = info_class;
|
||||
if (length > fixed_size) wine_server_set_reply( req, ptr, length - fixed_size );
|
||||
if (!(ret = wine_server_call( req )))
|
||||
{
|
||||
copy_key_value_info( info_class, info, length, reply->type, reply->namelen,
|
||||
wine_server_reply_size(reply) - reply->namelen );
|
||||
*result_len = fixed_size + reply->total;
|
||||
if (length < *result_len) ret = STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtQueryValueKey [NTDLL.@]
|
||||
* ZwQueryValueKey [NTDLL.@]
|
||||
*
|
||||
* NOTES
|
||||
* the name in the KeyValueInformation is never set
|
||||
*/
|
||||
NTSTATUS WINAPI DECLSPEC_HOTPATCH NtQueryValueKey( HANDLE handle, const UNICODE_STRING *name,
|
||||
KEY_VALUE_INFORMATION_CLASS info_class,
|
||||
void *info, DWORD length, DWORD *result_len )
|
||||
{
|
||||
NTSTATUS ret;
|
||||
UCHAR *data_ptr;
|
||||
unsigned int fixed_size, min_size;
|
||||
|
||||
TRACE( "(%p,%s,%d,%p,%d)\n", handle, debugstr_us(name), info_class, info, length );
|
||||
|
||||
if (name->Length > MAX_VALUE_LENGTH) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
/* compute the length we want to retrieve */
|
||||
switch(info_class)
|
||||
{
|
||||
case KeyValueBasicInformation:
|
||||
{
|
||||
KEY_VALUE_BASIC_INFORMATION *basic_info = info;
|
||||
min_size = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name);
|
||||
fixed_size = min_size + name->Length;
|
||||
if (min_size < length)
|
||||
memcpy(basic_info->Name, name->Buffer, min(length - min_size, name->Length));
|
||||
data_ptr = NULL;
|
||||
break;
|
||||
}
|
||||
case KeyValueFullInformation:
|
||||
{
|
||||
KEY_VALUE_FULL_INFORMATION *full_info = info;
|
||||
min_size = FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name);
|
||||
fixed_size = min_size + name->Length;
|
||||
if (min_size < length)
|
||||
memcpy(full_info->Name, name->Buffer, min(length - min_size, name->Length));
|
||||
data_ptr = (UCHAR *)full_info->Name + name->Length;
|
||||
break;
|
||||
}
|
||||
case KeyValuePartialInformation:
|
||||
min_size = fixed_size = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
|
||||
data_ptr = ((KEY_VALUE_PARTIAL_INFORMATION *)info)->Data;
|
||||
break;
|
||||
default:
|
||||
FIXME( "Information class %d not implemented\n", info_class );
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
SERVER_START_REQ( get_key_value )
|
||||
{
|
||||
req->hkey = wine_server_obj_handle( handle );
|
||||
wine_server_add_data( req, name->Buffer, name->Length );
|
||||
if (length > fixed_size && data_ptr) wine_server_set_reply( req, data_ptr, length - fixed_size );
|
||||
if (!(ret = wine_server_call( req )))
|
||||
{
|
||||
copy_key_value_info( info_class, info, length, reply->type,
|
||||
name->Length, reply->total );
|
||||
*result_len = fixed_size + (info_class == KeyValueBasicInformation ? 0 : reply->total);
|
||||
if (length < min_size) ret = STATUS_BUFFER_TOO_SMALL;
|
||||
else if (length < *result_len) ret = STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* RtlpNtQueryValueKey [NTDLL.@]
|
||||
*
|
||||
|
@ -623,257 +163,6 @@ NTSTATUS WINAPI RtlpNtQueryValueKey( HANDLE handle, ULONG *result_type, PBYTE de
|
|||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* NtFlushKey [NTDLL.@]
|
||||
* ZwFlushKey [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI NtFlushKey(HANDLE key)
|
||||
{
|
||||
NTSTATUS ret;
|
||||
|
||||
TRACE("key=%p\n", key);
|
||||
|
||||
SERVER_START_REQ( flush_key )
|
||||
{
|
||||
req->hkey = wine_server_obj_handle( key );
|
||||
ret = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* NtLoadKey [NTDLL.@]
|
||||
* ZwLoadKey [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI NtLoadKey( const OBJECT_ATTRIBUTES *attr, OBJECT_ATTRIBUTES *file )
|
||||
{
|
||||
NTSTATUS ret;
|
||||
HANDLE hive;
|
||||
IO_STATUS_BLOCK io;
|
||||
data_size_t len;
|
||||
struct object_attributes *objattr;
|
||||
|
||||
TRACE("(%p,%p)\n", attr, file);
|
||||
|
||||
ret = NtCreateFile(&hive, GENERIC_READ | SYNCHRONIZE, file, &io, NULL, FILE_ATTRIBUTE_NORMAL, 0,
|
||||
FILE_OPEN, 0, NULL, 0);
|
||||
if (ret) return ret;
|
||||
|
||||
if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret;
|
||||
|
||||
SERVER_START_REQ( load_registry )
|
||||
{
|
||||
req->file = wine_server_obj_handle( hive );
|
||||
wine_server_add_data( req, objattr, len );
|
||||
ret = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
NtClose(hive);
|
||||
RtlFreeHeap( GetProcessHeap(), 0, objattr );
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* NtLoadKey2 [NTDLL.@]
|
||||
* ZwLoadKey2 [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI NtLoadKey2(OBJECT_ATTRIBUTES *attr, OBJECT_ATTRIBUTES *file, ULONG flags)
|
||||
{
|
||||
FIXME("(%p,%p,0x%08x) semi-stub: ignoring flags\n", attr, file, flags);
|
||||
return NtLoadKey(attr, file);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* NtNotifyChangeMultipleKeys [NTDLL.@]
|
||||
* ZwNotifyChangeMultipleKeys [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI NtNotifyChangeMultipleKeys(
|
||||
HANDLE KeyHandle,
|
||||
ULONG Count,
|
||||
OBJECT_ATTRIBUTES *SubordinateObjects,
|
||||
HANDLE Event,
|
||||
PIO_APC_ROUTINE ApcRoutine,
|
||||
PVOID ApcContext,
|
||||
PIO_STATUS_BLOCK IoStatusBlock,
|
||||
ULONG CompletionFilter,
|
||||
BOOLEAN WatchSubtree,
|
||||
PVOID ChangeBuffer,
|
||||
ULONG Length,
|
||||
BOOLEAN Asynchronous)
|
||||
{
|
||||
NTSTATUS ret;
|
||||
|
||||
TRACE("(%p,%u,%p,%p,%p,%p,%p,0x%08x, 0x%08x,%p,0x%08x,0x%08x)\n",
|
||||
KeyHandle, Count, SubordinateObjects, Event, ApcRoutine, ApcContext, IoStatusBlock, CompletionFilter,
|
||||
Asynchronous, ChangeBuffer, Length, WatchSubtree);
|
||||
|
||||
if (Count || SubordinateObjects || ApcRoutine || ApcContext || ChangeBuffer || Length)
|
||||
FIXME("Unimplemented optional parameter\n");
|
||||
|
||||
if (!Asynchronous)
|
||||
{
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
InitializeObjectAttributes( &attr, NULL, 0, NULL, NULL );
|
||||
ret = NtCreateEvent( &Event, EVENT_ALL_ACCESS, &attr, SynchronizationEvent, FALSE );
|
||||
if (ret != STATUS_SUCCESS)
|
||||
return ret;
|
||||
}
|
||||
|
||||
SERVER_START_REQ( set_registry_notification )
|
||||
{
|
||||
req->hkey = wine_server_obj_handle( KeyHandle );
|
||||
req->event = wine_server_obj_handle( Event );
|
||||
req->subtree = WatchSubtree;
|
||||
req->filter = CompletionFilter;
|
||||
ret = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if (!Asynchronous)
|
||||
{
|
||||
if (ret == STATUS_PENDING)
|
||||
ret = NtWaitForSingleObject( Event, FALSE, NULL );
|
||||
NtClose( Event );
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* NtNotifyChangeKey [NTDLL.@]
|
||||
* ZwNotifyChangeKey [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI NtNotifyChangeKey(
|
||||
IN HANDLE KeyHandle,
|
||||
IN HANDLE Event,
|
||||
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
|
||||
IN PVOID ApcContext OPTIONAL,
|
||||
OUT PIO_STATUS_BLOCK IoStatusBlock,
|
||||
IN ULONG CompletionFilter,
|
||||
IN BOOLEAN WatchSubtree,
|
||||
OUT PVOID ChangeBuffer,
|
||||
IN ULONG Length,
|
||||
IN BOOLEAN Asynchronous)
|
||||
{
|
||||
return NtNotifyChangeMultipleKeys(KeyHandle, 0, NULL, Event, ApcRoutine, ApcContext,
|
||||
IoStatusBlock, CompletionFilter, WatchSubtree,
|
||||
ChangeBuffer, Length, Asynchronous);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* NtQueryMultipleValueKey [NTDLL]
|
||||
* ZwQueryMultipleValueKey
|
||||
*/
|
||||
|
||||
NTSTATUS WINAPI NtQueryMultipleValueKey(
|
||||
HANDLE KeyHandle,
|
||||
PKEY_MULTIPLE_VALUE_INFORMATION ListOfValuesToQuery,
|
||||
ULONG NumberOfItems,
|
||||
PVOID MultipleValueInformation,
|
||||
ULONG Length,
|
||||
PULONG ReturnLength)
|
||||
{
|
||||
FIXME("(%p,%p,0x%08x,%p,0x%08x,%p) stub!\n",
|
||||
KeyHandle, ListOfValuesToQuery, NumberOfItems, MultipleValueInformation,
|
||||
Length,ReturnLength);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* NtReplaceKey [NTDLL.@]
|
||||
* ZwReplaceKey [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI NtReplaceKey(
|
||||
IN POBJECT_ATTRIBUTES ObjectAttributes,
|
||||
IN HANDLE Key,
|
||||
IN POBJECT_ATTRIBUTES ReplacedObjectAttributes)
|
||||
{
|
||||
FIXME("(%s,%p,%s),stub!\n", debugstr_ObjectAttributes(ObjectAttributes), Key,
|
||||
debugstr_ObjectAttributes(ReplacedObjectAttributes) );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
/******************************************************************************
|
||||
* NtRestoreKey [NTDLL.@]
|
||||
* ZwRestoreKey [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI NtRestoreKey(
|
||||
HANDLE KeyHandle,
|
||||
HANDLE FileHandle,
|
||||
ULONG RestoreFlags)
|
||||
{
|
||||
FIXME("(%p,%p,0x%08x) stub\n",
|
||||
KeyHandle, FileHandle, RestoreFlags);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
/******************************************************************************
|
||||
* NtSaveKey [NTDLL.@]
|
||||
* ZwSaveKey [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI NtSaveKey(IN HANDLE KeyHandle, IN HANDLE FileHandle)
|
||||
{
|
||||
NTSTATUS ret;
|
||||
|
||||
TRACE("(%p,%p)\n", KeyHandle, FileHandle);
|
||||
|
||||
SERVER_START_REQ( save_registry )
|
||||
{
|
||||
req->hkey = wine_server_obj_handle( KeyHandle );
|
||||
req->file = wine_server_obj_handle( FileHandle );
|
||||
ret = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
return ret;
|
||||
}
|
||||
/******************************************************************************
|
||||
* NtSetInformationKey [NTDLL.@]
|
||||
* ZwSetInformationKey [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI NtSetInformationKey(
|
||||
IN HANDLE KeyHandle,
|
||||
IN const int KeyInformationClass,
|
||||
IN PVOID KeyInformation,
|
||||
IN ULONG KeyInformationLength)
|
||||
{
|
||||
FIXME("(%p,0x%08x,%p,0x%08x) stub\n",
|
||||
KeyHandle, KeyInformationClass, KeyInformation, KeyInformationLength);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtSetValueKey [NTDLL.@]
|
||||
* ZwSetValueKey [NTDLL.@]
|
||||
*
|
||||
* NOTES
|
||||
* win95 does not care about count for REG_SZ and finds out the len by itself (js)
|
||||
* NT does definitely care (aj)
|
||||
*/
|
||||
NTSTATUS WINAPI NtSetValueKey( HANDLE hkey, const UNICODE_STRING *name, ULONG TitleIndex,
|
||||
ULONG type, const void *data, ULONG count )
|
||||
{
|
||||
NTSTATUS ret;
|
||||
|
||||
TRACE( "(%p,%s,%d,%p,%d)\n", hkey, debugstr_us(name), type, data, count );
|
||||
|
||||
if (name->Length > MAX_VALUE_LENGTH) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
SERVER_START_REQ( set_key_value )
|
||||
{
|
||||
req->hkey = wine_server_obj_handle( hkey );
|
||||
req->type = type;
|
||||
req->namelen = name->Length;
|
||||
wine_server_add_data( req, name->Buffer, name->Length );
|
||||
wine_server_add_data( req, data, count );
|
||||
ret = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* RtlpNtSetValueKey [NTDLL.@]
|
||||
*
|
||||
|
@ -887,26 +176,6 @@ NTSTATUS WINAPI RtlpNtSetValueKey( HANDLE hkey, ULONG type, const void *data,
|
|||
return NtSetValueKey( hkey, &name, 0, type, data, count );
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* NtUnloadKey [NTDLL.@]
|
||||
* ZwUnloadKey [NTDLL.@]
|
||||
*/
|
||||
NTSTATUS WINAPI NtUnloadKey(IN POBJECT_ATTRIBUTES attr)
|
||||
{
|
||||
NTSTATUS ret;
|
||||
|
||||
TRACE("(%p)\n", attr);
|
||||
|
||||
SERVER_START_REQ( unload_registry )
|
||||
{
|
||||
req->hkey = wine_server_obj_handle( attr->RootDirectory );
|
||||
ret = wine_server_call(req);
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* RtlFormatCurrentUserKeyPath [NTDLL.@]
|
||||
*
|
||||
|
@ -1527,67 +796,3 @@ NTSTATUS WINAPI RtlWriteRegistryValue( ULONG RelativeTo, PCWSTR path, PCWSTR nam
|
|||
|
||||
return status;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* NtQueryLicenseValue [NTDLL.@]
|
||||
*
|
||||
* NOTES
|
||||
* On Windows all license properties are stored in a single key, but
|
||||
* unless there is some app which explicitly depends on that, there is
|
||||
* no good reason to reproduce that.
|
||||
*/
|
||||
NTSTATUS WINAPI NtQueryLicenseValue( const UNICODE_STRING *name, ULONG *result_type,
|
||||
PVOID data, ULONG length, ULONG *result_len )
|
||||
{
|
||||
static const WCHAR LicenseInformationW[] = {'M','a','c','h','i','n','e','\\',
|
||||
'S','o','f','t','w','a','r','e','\\',
|
||||
'W','i','n','e','\\','L','i','c','e','n','s','e',
|
||||
'I','n','f','o','r','m','a','t','i','o','n',0};
|
||||
KEY_VALUE_PARTIAL_INFORMATION *info;
|
||||
NTSTATUS status = STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
DWORD info_length, count;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
UNICODE_STRING keyW;
|
||||
HANDLE hkey;
|
||||
|
||||
if (!name || !name->Buffer || !name->Length || !result_len)
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
|
||||
info_length = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data) + length;
|
||||
info = RtlAllocateHeap( GetProcessHeap(), 0, info_length );
|
||||
if (!info) return STATUS_NO_MEMORY;
|
||||
|
||||
attr.Length = sizeof(attr);
|
||||
attr.RootDirectory = 0;
|
||||
attr.ObjectName = &keyW;
|
||||
attr.Attributes = 0;
|
||||
attr.SecurityDescriptor = NULL;
|
||||
attr.SecurityQualityOfService = NULL;
|
||||
RtlInitUnicodeString( &keyW, LicenseInformationW );
|
||||
|
||||
/* @@ Wine registry key: HKLM\Software\Wine\LicenseInformation */
|
||||
if (!NtOpenKey( &hkey, KEY_READ, &attr ))
|
||||
{
|
||||
status = NtQueryValueKey( hkey, name, KeyValuePartialInformation,
|
||||
info, info_length, &count );
|
||||
if (!status || status == STATUS_BUFFER_OVERFLOW)
|
||||
{
|
||||
if (result_type)
|
||||
*result_type = info->Type;
|
||||
|
||||
*result_len = info->DataLength;
|
||||
|
||||
if (status == STATUS_BUFFER_OVERFLOW)
|
||||
status = STATUS_BUFFER_TOO_SMALL;
|
||||
else
|
||||
memcpy( data, info->Data, info->DataLength );
|
||||
}
|
||||
NtClose( hkey );
|
||||
}
|
||||
|
||||
if (status == STATUS_OBJECT_NAME_NOT_FOUND)
|
||||
FIXME( "License key %s not found\n", debugstr_w(name->Buffer) );
|
||||
|
||||
RtlFreeHeap( GetProcessHeap(), 0, info );
|
||||
return status;
|
||||
}
|
||||
|
|
778
dlls/ntdll/unix/registry.c
Normal file
778
dlls/ntdll/unix/registry.c
Normal file
|
@ -0,0 +1,778 @@
|
|||
/*
|
||||
* Registry functions
|
||||
*
|
||||
* Copyright 1999 Juergen Schmied
|
||||
* Copyright 2000 Alexandre Julliard
|
||||
* Copyright 2005 Ivan Leo Puoti, Laurent Pinchart
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library 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
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#pragma makedep unix
|
||||
#endif
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ntstatus.h"
|
||||
#define WIN32_NO_STATUS
|
||||
#include "unix_private.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(reg);
|
||||
|
||||
/* maximum length of a value name in bytes (without terminating null) */
|
||||
#define MAX_VALUE_LENGTH (16383 * sizeof(WCHAR))
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtCreateKey (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtCreateKey( HANDLE *key, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr,
|
||||
ULONG index, const UNICODE_STRING *class, ULONG options, ULONG *dispos )
|
||||
{
|
||||
NTSTATUS ret;
|
||||
data_size_t len;
|
||||
struct object_attributes *objattr;
|
||||
|
||||
if (!key || !attr) return STATUS_ACCESS_VIOLATION;
|
||||
if (attr->Length > sizeof(OBJECT_ATTRIBUTES)) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
TRACE( "(%p,%s,%s,%x,%x,%p)\n", attr->RootDirectory, debugstr_us(attr->ObjectName),
|
||||
debugstr_us(class), options, access, key );
|
||||
|
||||
if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret;
|
||||
|
||||
SERVER_START_REQ( create_key )
|
||||
{
|
||||
req->access = access;
|
||||
req->options = options;
|
||||
wine_server_add_data( req, objattr, len );
|
||||
if (class) wine_server_add_data( req, class->Buffer, class->Length );
|
||||
ret = wine_server_call( req );
|
||||
*key = wine_server_ptr_handle( reply->hkey );
|
||||
if (dispos && !ret) *dispos = reply->created ? REG_CREATED_NEW_KEY : REG_OPENED_EXISTING_KEY;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
TRACE( "<- %p\n", *key );
|
||||
free( objattr );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtCreateKeyTransacted (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtCreateKeyTransacted( HANDLE *key, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr,
|
||||
ULONG index, const UNICODE_STRING *class, ULONG options,
|
||||
HANDLE transacted, ULONG *dispos )
|
||||
{
|
||||
FIXME( "(%p,%s,%s,%x,%x,%p,%p)\n", attr->RootDirectory, debugstr_us(attr->ObjectName),
|
||||
debugstr_us(class), options, access, transacted, key );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtOpenKeyEx (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtOpenKeyEx( HANDLE *key, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr, ULONG options )
|
||||
{
|
||||
NTSTATUS ret;
|
||||
|
||||
if (!key || !attr || !attr->ObjectName) return STATUS_ACCESS_VIOLATION;
|
||||
if (attr->Length != sizeof(*attr)) return STATUS_INVALID_PARAMETER;
|
||||
if (attr->ObjectName->Length & 1) return STATUS_OBJECT_NAME_INVALID;
|
||||
|
||||
TRACE( "(%p,%s,%x,%p)\n", attr->RootDirectory, debugstr_us(attr->ObjectName), access, key );
|
||||
|
||||
if (options & ~REG_OPTION_OPEN_LINK) FIXME( "options %x not implemented\n", options );
|
||||
|
||||
SERVER_START_REQ( open_key )
|
||||
{
|
||||
req->parent = wine_server_obj_handle( attr->RootDirectory );
|
||||
req->access = access;
|
||||
req->attributes = attr->Attributes;
|
||||
wine_server_add_data( req, attr->ObjectName->Buffer, attr->ObjectName->Length );
|
||||
ret = wine_server_call( req );
|
||||
*key = wine_server_ptr_handle( reply->hkey );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
TRACE("<- %p\n", *key);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtOpenKey (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtOpenKey( HANDLE *key, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr )
|
||||
{
|
||||
return NtOpenKeyEx( key, access, attr, 0 );
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtOpenKeyTransactedEx (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtOpenKeyTransactedEx( HANDLE *key, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr,
|
||||
ULONG options, HANDLE transaction )
|
||||
{
|
||||
FIXME( "(%p %x %p %x %p)\n", key, access, attr, options, transaction );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtOpenKeyTransacted (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtOpenKeyTransacted( HANDLE *key, ACCESS_MASK access, const OBJECT_ATTRIBUTES *attr,
|
||||
HANDLE transaction )
|
||||
{
|
||||
return NtOpenKeyTransactedEx( key, access, attr, 0, transaction );
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtDeleteKey (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtDeleteKey( HANDLE key )
|
||||
{
|
||||
NTSTATUS ret;
|
||||
|
||||
TRACE( "(%p)\n", key );
|
||||
|
||||
SERVER_START_REQ( delete_key )
|
||||
{
|
||||
req->hkey = wine_server_obj_handle( key );
|
||||
ret = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtRenameKey (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtRenameKey( HANDLE handle, UNICODE_STRING *name )
|
||||
{
|
||||
FIXME( "(%p %s)\n", handle, debugstr_us(name) );
|
||||
return STATUS_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* enumerate_key
|
||||
*
|
||||
* Implementation of NtQueryKey and NtEnumerateKey
|
||||
*/
|
||||
static NTSTATUS enumerate_key( HANDLE handle, int index, KEY_INFORMATION_CLASS info_class,
|
||||
void *info, DWORD length, DWORD *result_len )
|
||||
|
||||
{
|
||||
NTSTATUS ret;
|
||||
void *data_ptr;
|
||||
size_t fixed_size;
|
||||
|
||||
switch (info_class)
|
||||
{
|
||||
case KeyBasicInformation: data_ptr = ((KEY_BASIC_INFORMATION *)info)->Name; break;
|
||||
case KeyFullInformation: data_ptr = ((KEY_FULL_INFORMATION *)info)->Class; break;
|
||||
case KeyNodeInformation: data_ptr = ((KEY_NODE_INFORMATION *)info)->Name; break;
|
||||
case KeyNameInformation: data_ptr = ((KEY_NAME_INFORMATION *)info)->Name; break;
|
||||
case KeyCachedInformation: data_ptr = ((KEY_CACHED_INFORMATION *)info)+1; break;
|
||||
default:
|
||||
FIXME( "Information class %d not implemented\n", info_class );
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
fixed_size = (char *)data_ptr - (char *)info;
|
||||
|
||||
SERVER_START_REQ( enum_key )
|
||||
{
|
||||
req->hkey = wine_server_obj_handle( handle );
|
||||
req->index = index;
|
||||
req->info_class = info_class;
|
||||
if (length > fixed_size) wine_server_set_reply( req, data_ptr, length - fixed_size );
|
||||
if (!(ret = wine_server_call( req )))
|
||||
{
|
||||
switch (info_class)
|
||||
{
|
||||
case KeyBasicInformation:
|
||||
{
|
||||
KEY_BASIC_INFORMATION keyinfo;
|
||||
fixed_size = (char *)keyinfo.Name - (char *)&keyinfo;
|
||||
keyinfo.LastWriteTime.QuadPart = reply->modif;
|
||||
keyinfo.TitleIndex = 0;
|
||||
keyinfo.NameLength = reply->namelen;
|
||||
memcpy( info, &keyinfo, min( length, fixed_size ) );
|
||||
break;
|
||||
}
|
||||
|
||||
case KeyFullInformation:
|
||||
{
|
||||
KEY_FULL_INFORMATION keyinfo;
|
||||
fixed_size = (char *)keyinfo.Class - (char *)&keyinfo;
|
||||
keyinfo.LastWriteTime.QuadPart = reply->modif;
|
||||
keyinfo.TitleIndex = 0;
|
||||
keyinfo.ClassLength = wine_server_reply_size(reply);
|
||||
keyinfo.ClassOffset = keyinfo.ClassLength ? fixed_size : -1;
|
||||
keyinfo.SubKeys = reply->subkeys;
|
||||
keyinfo.MaxNameLen = reply->max_subkey;
|
||||
keyinfo.MaxClassLen = reply->max_class;
|
||||
keyinfo.Values = reply->values;
|
||||
keyinfo.MaxValueNameLen = reply->max_value;
|
||||
keyinfo.MaxValueDataLen = reply->max_data;
|
||||
memcpy( info, &keyinfo, min( length, fixed_size ) );
|
||||
break;
|
||||
}
|
||||
|
||||
case KeyNodeInformation:
|
||||
{
|
||||
KEY_NODE_INFORMATION keyinfo;
|
||||
fixed_size = (char *)keyinfo.Name - (char *)&keyinfo;
|
||||
keyinfo.LastWriteTime.QuadPart = reply->modif;
|
||||
keyinfo.TitleIndex = 0;
|
||||
if (reply->namelen < wine_server_reply_size(reply))
|
||||
{
|
||||
keyinfo.ClassLength = wine_server_reply_size(reply) - reply->namelen;
|
||||
keyinfo.ClassOffset = fixed_size + reply->namelen;
|
||||
}
|
||||
else
|
||||
{
|
||||
keyinfo.ClassLength = 0;
|
||||
keyinfo.ClassOffset = -1;
|
||||
}
|
||||
keyinfo.NameLength = reply->namelen;
|
||||
memcpy( info, &keyinfo, min( length, fixed_size ) );
|
||||
break;
|
||||
}
|
||||
|
||||
case KeyNameInformation:
|
||||
{
|
||||
KEY_NAME_INFORMATION keyinfo;
|
||||
fixed_size = (char *)keyinfo.Name - (char *)&keyinfo;
|
||||
keyinfo.NameLength = reply->namelen;
|
||||
memcpy( info, &keyinfo, min( length, fixed_size ) );
|
||||
break;
|
||||
}
|
||||
|
||||
case KeyCachedInformation:
|
||||
{
|
||||
KEY_CACHED_INFORMATION keyinfo;
|
||||
fixed_size = sizeof(keyinfo);
|
||||
keyinfo.LastWriteTime.QuadPart = reply->modif;
|
||||
keyinfo.TitleIndex = 0;
|
||||
keyinfo.SubKeys = reply->subkeys;
|
||||
keyinfo.MaxNameLen = reply->max_subkey;
|
||||
keyinfo.Values = reply->values;
|
||||
keyinfo.MaxValueNameLen = reply->max_value;
|
||||
keyinfo.MaxValueDataLen = reply->max_data;
|
||||
keyinfo.NameLength = reply->namelen;
|
||||
memcpy( info, &keyinfo, min( length, fixed_size ) );
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
*result_len = fixed_size + reply->total;
|
||||
if (length < *result_len) ret = STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtEnumerateKey (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtEnumerateKey( HANDLE handle, ULONG index, KEY_INFORMATION_CLASS info_class,
|
||||
void *info, DWORD length, DWORD *result_len )
|
||||
{
|
||||
/* -1 means query key, so avoid it here */
|
||||
if (index == (ULONG)-1) return STATUS_NO_MORE_ENTRIES;
|
||||
return enumerate_key( handle, index, info_class, info, length, result_len );
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtQueryKey (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtQueryKey( HANDLE handle, KEY_INFORMATION_CLASS info_class,
|
||||
void *info, DWORD length, DWORD *result_len )
|
||||
{
|
||||
return enumerate_key( handle, -1, info_class, info, length, result_len );
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtSetInformationKey (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtSetInformationKey( HANDLE key, int class, void *info, ULONG length )
|
||||
{
|
||||
FIXME( "(%p,0x%08x,%p,0x%08x) stub\n", key, class, info, length );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* fill the key value info structure for a specific info class */
|
||||
static void copy_key_value_info( KEY_VALUE_INFORMATION_CLASS info_class, void *info,
|
||||
DWORD length, int type, int name_len, int data_len )
|
||||
{
|
||||
switch (info_class)
|
||||
{
|
||||
case KeyValueBasicInformation:
|
||||
{
|
||||
KEY_VALUE_BASIC_INFORMATION keyinfo;
|
||||
keyinfo.TitleIndex = 0;
|
||||
keyinfo.Type = type;
|
||||
keyinfo.NameLength = name_len;
|
||||
length = min( length, (char *)keyinfo.Name - (char *)&keyinfo );
|
||||
memcpy( info, &keyinfo, length );
|
||||
break;
|
||||
}
|
||||
|
||||
case KeyValueFullInformation:
|
||||
{
|
||||
KEY_VALUE_FULL_INFORMATION keyinfo;
|
||||
keyinfo.TitleIndex = 0;
|
||||
keyinfo.Type = type;
|
||||
keyinfo.DataOffset = (char *)keyinfo.Name - (char *)&keyinfo + name_len;
|
||||
keyinfo.DataLength = data_len;
|
||||
keyinfo.NameLength = name_len;
|
||||
length = min( length, (char *)keyinfo.Name - (char *)&keyinfo );
|
||||
memcpy( info, &keyinfo, length );
|
||||
break;
|
||||
}
|
||||
|
||||
case KeyValuePartialInformation:
|
||||
{
|
||||
KEY_VALUE_PARTIAL_INFORMATION keyinfo;
|
||||
keyinfo.TitleIndex = 0;
|
||||
keyinfo.Type = type;
|
||||
keyinfo.DataLength = data_len;
|
||||
length = min( length, (char *)keyinfo.Data - (char *)&keyinfo );
|
||||
memcpy( info, &keyinfo, length );
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtEnumerateValueKey (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtEnumerateValueKey( HANDLE handle, ULONG index, KEY_VALUE_INFORMATION_CLASS info_class,
|
||||
void *info, DWORD length, DWORD *result_len )
|
||||
{
|
||||
NTSTATUS ret;
|
||||
void *ptr;
|
||||
size_t fixed_size;
|
||||
|
||||
TRACE( "(%p,%u,%d,%p,%d)\n", handle, index, info_class, info, length );
|
||||
|
||||
/* compute the length we want to retrieve */
|
||||
switch (info_class)
|
||||
{
|
||||
case KeyValueBasicInformation: ptr = ((KEY_VALUE_BASIC_INFORMATION *)info)->Name; break;
|
||||
case KeyValueFullInformation: ptr = ((KEY_VALUE_FULL_INFORMATION *)info)->Name; break;
|
||||
case KeyValuePartialInformation: ptr = ((KEY_VALUE_PARTIAL_INFORMATION *)info)->Data; break;
|
||||
default:
|
||||
FIXME( "Information class %d not implemented\n", info_class );
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
fixed_size = (char *)ptr - (char *)info;
|
||||
|
||||
SERVER_START_REQ( enum_key_value )
|
||||
{
|
||||
req->hkey = wine_server_obj_handle( handle );
|
||||
req->index = index;
|
||||
req->info_class = info_class;
|
||||
if (length > fixed_size) wine_server_set_reply( req, ptr, length - fixed_size );
|
||||
if (!(ret = wine_server_call( req )))
|
||||
{
|
||||
copy_key_value_info( info_class, info, length, reply->type, reply->namelen,
|
||||
wine_server_reply_size(reply) - reply->namelen );
|
||||
*result_len = fixed_size + reply->total;
|
||||
if (length < *result_len) ret = STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtQueryValueKey (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtQueryValueKey( HANDLE handle, const UNICODE_STRING *name,
|
||||
KEY_VALUE_INFORMATION_CLASS info_class,
|
||||
void *info, DWORD length, DWORD *result_len )
|
||||
{
|
||||
NTSTATUS ret;
|
||||
UCHAR *data_ptr;
|
||||
unsigned int fixed_size, min_size;
|
||||
|
||||
TRACE( "(%p,%s,%d,%p,%d)\n", handle, debugstr_us(name), info_class, info, length );
|
||||
|
||||
if (name->Length > MAX_VALUE_LENGTH) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
/* compute the length we want to retrieve */
|
||||
switch(info_class)
|
||||
{
|
||||
case KeyValueBasicInformation:
|
||||
{
|
||||
KEY_VALUE_BASIC_INFORMATION *basic_info = info;
|
||||
min_size = FIELD_OFFSET(KEY_VALUE_BASIC_INFORMATION, Name);
|
||||
fixed_size = min_size + name->Length;
|
||||
if (min_size < length)
|
||||
memcpy(basic_info->Name, name->Buffer, min(length - min_size, name->Length));
|
||||
data_ptr = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
case KeyValueFullInformation:
|
||||
{
|
||||
KEY_VALUE_FULL_INFORMATION *full_info = info;
|
||||
min_size = FIELD_OFFSET(KEY_VALUE_FULL_INFORMATION, Name);
|
||||
fixed_size = min_size + name->Length;
|
||||
if (min_size < length)
|
||||
memcpy(full_info->Name, name->Buffer, min(length - min_size, name->Length));
|
||||
data_ptr = (UCHAR *)full_info->Name + name->Length;
|
||||
break;
|
||||
}
|
||||
|
||||
case KeyValuePartialInformation:
|
||||
min_size = fixed_size = FIELD_OFFSET(KEY_VALUE_PARTIAL_INFORMATION, Data);
|
||||
data_ptr = ((KEY_VALUE_PARTIAL_INFORMATION *)info)->Data;
|
||||
break;
|
||||
|
||||
default:
|
||||
FIXME( "Information class %d not implemented\n", info_class );
|
||||
return STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
SERVER_START_REQ( get_key_value )
|
||||
{
|
||||
req->hkey = wine_server_obj_handle( handle );
|
||||
wine_server_add_data( req, name->Buffer, name->Length );
|
||||
if (length > fixed_size && data_ptr) wine_server_set_reply( req, data_ptr, length - fixed_size );
|
||||
if (!(ret = wine_server_call( req )))
|
||||
{
|
||||
copy_key_value_info( info_class, info, length, reply->type,
|
||||
name->Length, reply->total );
|
||||
*result_len = fixed_size + (info_class == KeyValueBasicInformation ? 0 : reply->total);
|
||||
if (length < min_size) ret = STATUS_BUFFER_TOO_SMALL;
|
||||
else if (length < *result_len) ret = STATUS_BUFFER_OVERFLOW;
|
||||
}
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtQueryMultipleValueKey (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtQueryMultipleValueKey( HANDLE key, KEY_MULTIPLE_VALUE_INFORMATION *info,
|
||||
ULONG count, void *buffer, ULONG length, ULONG *retlen )
|
||||
{
|
||||
FIXME( "(%p,%p,0x%08x,%p,0x%08x,%p) stub!\n", key, info, count, buffer, length, retlen );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtSetValueKey (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtSetValueKey( HANDLE key, const UNICODE_STRING *name, ULONG index,
|
||||
ULONG type, const void *data, ULONG count )
|
||||
{
|
||||
NTSTATUS ret;
|
||||
|
||||
TRACE( "(%p,%s,%d,%p,%d)\n", key, debugstr_us(name), type, data, count );
|
||||
|
||||
if (name->Length > MAX_VALUE_LENGTH) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
SERVER_START_REQ( set_key_value )
|
||||
{
|
||||
req->hkey = wine_server_obj_handle( key );
|
||||
req->type = type;
|
||||
req->namelen = name->Length;
|
||||
wine_server_add_data( req, name->Buffer, name->Length );
|
||||
wine_server_add_data( req, data, count );
|
||||
ret = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtDeleteValueKey (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtDeleteValueKey( HANDLE key, const UNICODE_STRING *name )
|
||||
{
|
||||
NTSTATUS ret;
|
||||
|
||||
TRACE( "(%p,%s)\n", key, debugstr_us(name) );
|
||||
|
||||
if (name->Length > MAX_VALUE_LENGTH) return STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
|
||||
SERVER_START_REQ( delete_key_value )
|
||||
{
|
||||
req->hkey = wine_server_obj_handle( key );
|
||||
wine_server_add_data( req, name->Buffer, name->Length );
|
||||
ret = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtNotifyChangeMultipleKeys (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtNotifyChangeMultipleKeys( HANDLE key, ULONG count, OBJECT_ATTRIBUTES *attr,
|
||||
HANDLE event, PIO_APC_ROUTINE apc, void *apc_context,
|
||||
IO_STATUS_BLOCK *io, ULONG filter, BOOLEAN subtree,
|
||||
void *buffer, ULONG length, BOOLEAN async )
|
||||
{
|
||||
NTSTATUS ret;
|
||||
|
||||
TRACE( "(%p,%u,%p,%p,%p,%p,%p,0x%08x, 0x%08x,%p,0x%08x,0x%08x)\n",
|
||||
key, count, attr, event, apc, apc_context, io, filter, async, buffer, length, subtree );
|
||||
|
||||
if (count || attr || apc || apc_context || buffer || length)
|
||||
FIXME( "Unimplemented optional parameter\n" );
|
||||
|
||||
if (!async)
|
||||
{
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
InitializeObjectAttributes( &attr, NULL, 0, NULL, NULL );
|
||||
ret = NtCreateEvent( &event, EVENT_ALL_ACCESS, &attr, SynchronizationEvent, FALSE );
|
||||
if (ret) return ret;
|
||||
}
|
||||
|
||||
SERVER_START_REQ( set_registry_notification )
|
||||
{
|
||||
req->hkey = wine_server_obj_handle( key );
|
||||
req->event = wine_server_obj_handle( event );
|
||||
req->subtree = subtree;
|
||||
req->filter = filter;
|
||||
ret = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if (!async)
|
||||
{
|
||||
if (ret == STATUS_PENDING) ret = NtWaitForSingleObject( event, FALSE, NULL );
|
||||
NtClose( event );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtNotifyChangeKey (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtNotifyChangeKey( HANDLE key, HANDLE event, PIO_APC_ROUTINE apc, void *apc_context,
|
||||
IO_STATUS_BLOCK *io, ULONG filter, BOOLEAN subtree,
|
||||
void *buffer, ULONG length, BOOLEAN async )
|
||||
{
|
||||
return NtNotifyChangeMultipleKeys( key, 0, NULL, event, apc, apc_context,
|
||||
io, filter, subtree, buffer, length, async );
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtFlushKey (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtFlushKey( HANDLE key )
|
||||
{
|
||||
NTSTATUS ret;
|
||||
|
||||
TRACE( "key=%p\n", key );
|
||||
|
||||
SERVER_START_REQ( flush_key )
|
||||
{
|
||||
req->hkey = wine_server_obj_handle( key );
|
||||
ret = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtLoadKey (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtLoadKey( const OBJECT_ATTRIBUTES *attr, OBJECT_ATTRIBUTES *file )
|
||||
{
|
||||
NTSTATUS ret;
|
||||
HANDLE key;
|
||||
IO_STATUS_BLOCK io;
|
||||
data_size_t len;
|
||||
struct object_attributes *objattr;
|
||||
|
||||
TRACE("(%p,%p)\n", attr, file);
|
||||
|
||||
ret = NtCreateFile( &key, GENERIC_READ | SYNCHRONIZE, file, &io, NULL, FILE_ATTRIBUTE_NORMAL, 0,
|
||||
FILE_OPEN, 0, NULL, 0);
|
||||
if (ret) return ret;
|
||||
|
||||
if ((ret = alloc_object_attributes( attr, &objattr, &len ))) return ret;
|
||||
|
||||
SERVER_START_REQ( load_registry )
|
||||
{
|
||||
req->file = wine_server_obj_handle( key );
|
||||
wine_server_add_data( req, objattr, len );
|
||||
ret = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
NtClose( key );
|
||||
free( objattr );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtLoadKey2 (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtLoadKey2( const OBJECT_ATTRIBUTES *attr, OBJECT_ATTRIBUTES *file, ULONG flags )
|
||||
{
|
||||
FIXME( "(%p,%p,0x%08x) semi-stub: ignoring flags\n", attr, file, flags );
|
||||
return NtLoadKey( attr, file );
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtUnloadKey (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtUnloadKey( OBJECT_ATTRIBUTES *attr )
|
||||
{
|
||||
NTSTATUS ret;
|
||||
|
||||
TRACE( "(%p)\n", attr );
|
||||
|
||||
SERVER_START_REQ( unload_registry )
|
||||
{
|
||||
req->hkey = wine_server_obj_handle( attr->RootDirectory );
|
||||
ret = wine_server_call(req);
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtSaveKey (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtSaveKey( HANDLE key, HANDLE file )
|
||||
{
|
||||
NTSTATUS ret;
|
||||
|
||||
TRACE( "(%p,%p)\n", key, file );
|
||||
|
||||
SERVER_START_REQ( save_registry )
|
||||
{
|
||||
req->hkey = wine_server_obj_handle( key );
|
||||
req->file = wine_server_obj_handle( file );
|
||||
ret = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtRestoreKey (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtRestoreKey( HANDLE key, HANDLE file, ULONG flags )
|
||||
{
|
||||
FIXME( "(%p,%p,0x%08x) stub\n", key, file, flags );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* NtReplaceKey (NTDLL.@)
|
||||
*/
|
||||
NTSTATUS WINAPI NtReplaceKey( OBJECT_ATTRIBUTES *attr, HANDLE key, OBJECT_ATTRIBUTES *replace )
|
||||
{
|
||||
FIXME( "(%s,%p,%s),stub!\n", debugstr_us(attr->ObjectName), key, debugstr_us(replace->ObjectName) );
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* NtQueryLicenseValue (NTDLL.@)
|
||||
*
|
||||
* NOTES
|
||||
* On Windows all license properties are stored in a single key, but
|
||||
* unless there is some app which explicitly depends on that, there is
|
||||
* no good reason to reproduce that.
|
||||
*/
|
||||
NTSTATUS WINAPI NtQueryLicenseValue( const UNICODE_STRING *name, ULONG *type,
|
||||
void *data, ULONG length, ULONG *retlen )
|
||||
{
|
||||
static const WCHAR nameW[] = {'M','a','c','h','i','n','e','\\',
|
||||
'S','o','f','t','w','a','r','e','\\',
|
||||
'W','i','n','e','\\','L','i','c','e','n','s','e',
|
||||
'I','n','f','o','r','m','a','t','i','o','n',0};
|
||||
UNICODE_STRING keyW = { sizeof(nameW) - sizeof(WCHAR), sizeof(nameW), (WCHAR *)nameW };
|
||||
KEY_VALUE_PARTIAL_INFORMATION *info;
|
||||
NTSTATUS status = STATUS_OBJECT_NAME_NOT_FOUND;
|
||||
DWORD info_length, count;
|
||||
OBJECT_ATTRIBUTES attr;
|
||||
HANDLE key;
|
||||
|
||||
if (!name || !name->Buffer || !name->Length || !retlen) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
info_length = FIELD_OFFSET( KEY_VALUE_PARTIAL_INFORMATION, Data ) + length;
|
||||
if (!(info = malloc( info_length ))) return STATUS_NO_MEMORY;
|
||||
|
||||
InitializeObjectAttributes( &attr, &keyW, 0, 0, NULL );
|
||||
|
||||
/* @@ Wine registry key: HKLM\Software\Wine\LicenseInformation */
|
||||
if (!NtOpenKey( &key, KEY_READ, &attr ))
|
||||
{
|
||||
status = NtQueryValueKey( key, name, KeyValuePartialInformation, info, info_length, &count );
|
||||
if (!status || status == STATUS_BUFFER_OVERFLOW)
|
||||
{
|
||||
if (type) *type = info->Type;
|
||||
*retlen = info->DataLength;
|
||||
if (status == STATUS_BUFFER_OVERFLOW)
|
||||
status = STATUS_BUFFER_TOO_SMALL;
|
||||
else
|
||||
memcpy( data, info->Data, info->DataLength );
|
||||
}
|
||||
NtClose( key );
|
||||
}
|
||||
|
||||
if (status == STATUS_OBJECT_NAME_NOT_FOUND)
|
||||
FIXME( "License key %s not found\n", debugstr_w(name->Buffer) );
|
||||
|
||||
free( info );
|
||||
return status;
|
||||
}
|
Loading…
Reference in a new issue