[CMAKE]
authorAmine Khaldi <amine.khaldi@reactos.org>
Wed, 6 Apr 2011 16:00:24 +0000 (16:00 +0000)
committerAmine Khaldi <amine.khaldi@reactos.org>
Wed, 6 Apr 2011 16:00:24 +0000 (16:00 +0000)
* Sync to trunk r51266.

svn path=/branches/cmake-bringup/; revision=51268

118 files changed:
1  2 
base/applications/mscutils/servman/lang/pl-PL.rc
base/applications/network/ping/ping.c
base/applications/rapps/rapps/comctl32ocx.txt
base/applications/rapps/rapps/doublecommander.txt
base/applications/rapps/rapps/firefox36.txt
base/applications/rapps/rapps/libreoffice.txt
base/applications/rapps/rapps/mfc40.txt
base/applications/rapps/rapps/mirandaim.txt
base/applications/rapps/rapps/msxml3.txt
base/applications/rapps/rapps/scite.txt
base/applications/rapps/rapps/seamonkey.txt
base/applications/rapps/rapps/tahoma.txt
base/applications/rapps/rapps/vb5run.txt
base/applications/rapps/rapps/vb6run.txt
base/applications/rapps/rapps/vc2005sp1run.txt
base/applications/rapps/rapps/vc2008sp1run.txt
base/applications/rapps/rapps/vc6run.txt
base/applications/rapps/rapps/vlc.txt
base/applications/sndvol32/mixer.c
base/shell/cmd/dir.c
base/shell/cmd/lang/ru-RU.rc
base/shell/explorer/explorer-pl.rc
base/system/services/config.c
dll/cpl/desk/lang/pl-PL.rc
dll/cpl/usrmgr/groupprops.c
dll/cpl/usrmgr/groups.c
dll/cpl/usrmgr/userprops.c
dll/cpl/usrmgr/users.c
dll/ntdll/def/ntdll.spec
dll/ntdll/ldr/ldrapi.c
dll/ntdll/ldr/ldrinit.c
dll/ntdll/ldr/utils.c
dll/ntdll/rtl/libsupp.c
dll/win32/advapi32/reg/reg.c
dll/win32/advapi32/sec/lsa.c
dll/win32/gdi32/misc/misc.c
dll/win32/gdi32/objects/brush.c
dll/win32/gdi32/objects/pen.c
dll/win32/kernel32/file/curdir.c
dll/win32/kernel32/file/dir.c
dll/win32/kernel32/include/kernel32.h
dll/win32/kernel32/misc/console.c
dll/win32/kernel32/misc/dllmain.c
dll/win32/kernel32/misc/ldr.c
dll/win32/kernel32/process/procsup.c
dll/win32/lsasrv/lsarpc.c
dll/win32/shell32/lang/pl-PL.rc
dll/win32/shell32/shlfileop.c
dll/win32/syssetup/wizard.c
dll/win32/user32/misc/display.c
dll/win32/user32/windows/class.c
dll/win32/user32/windows/cursoricon.c
dll/win32/user32/windows/draw.c
dll/win32/user32/windows/input.c
dll/win32/user32/windows/menu.c
dll/win32/user32/windows/message.c
dll/win32/user32/windows/paint.c
include/ndk/ldrfuncs.h
include/ndk/ldrtypes.h
include/ndk/rtltypes.h
include/psdk/iphlpapi.h
include/psdk/ksmedia.h
include/psdk/winbase.h
include/reactos/idl/lsa.idl
include/reactos/libs/fullfat/ff_config.h
include/reactos/libs/fullfat/ff_crc.h
include/reactos/libs/fullfat/ff_dir.h
include/reactos/libs/fullfat/ff_error.h
include/reactos/libs/fullfat/ff_fat.h
include/reactos/libs/fullfat/ff_fatdef.h
include/reactos/libs/fullfat/ff_file.h
include/reactos/libs/fullfat/ff_format.h
include/reactos/libs/fullfat/ff_ioman.h
include/reactos/libs/fullfat/ff_memory.h
include/reactos/libs/fullfat/ff_string.h
include/reactos/libs/fullfat/ff_types.h
include/reactos/libs/fullfat/ff_unicode.h
include/reactos/libs/fullfat/fullfat.h
include/reactos/win32k/ntuser.h
lib/3rdparty/fullfat/ff_crc.c
lib/3rdparty/fullfat/ff_dir.c
lib/3rdparty/fullfat/ff_error.c
lib/3rdparty/fullfat/ff_fat.c
lib/3rdparty/fullfat/ff_file.c
lib/3rdparty/fullfat/ff_format.c
lib/3rdparty/fullfat/ff_hash.c
lib/3rdparty/fullfat/ff_ioman.c
lib/3rdparty/fullfat/ff_memory.c
lib/3rdparty/fullfat/ff_safety.c
lib/3rdparty/fullfat/ff_string.c
lib/3rdparty/fullfat/ff_unicode.c
lib/rtl/image.c
ntoskrnl/ke/apc.c
ntoskrnl/mm/ARM3/sysldr.c
ntoskrnl/mm/section.c
subsystems/win32/win32k/eng/device.c
subsystems/win32/win32k/include/focus.h
subsystems/win32/win32k/include/gdiobj.h
subsystems/win32/win32k/include/monitor.h
subsystems/win32/win32k/include/msgqueue.h
subsystems/win32/win32k/include/window.h
subsystems/win32/win32k/main/dllmain.c
subsystems/win32/win32k/ntuser/class.c
subsystems/win32/win32k/ntuser/display.c
subsystems/win32/win32k/ntuser/focus.c
subsystems/win32/win32k/ntuser/message.c
subsystems/win32/win32k/ntuser/misc.c
subsystems/win32/win32k/ntuser/monitor.c
subsystems/win32/win32k/ntuser/msgqueue.c
subsystems/win32/win32k/ntuser/ntstubs.c
subsystems/win32/win32k/ntuser/painting.c
subsystems/win32/win32k/ntuser/simplecall.c
subsystems/win32/win32k/ntuser/window.c
subsystems/win32/win32k/ntuser/winpos.c
subsystems/win32/win32k/objects/brush.c
subsystems/win32/win32k/objects/dclife.c
subsystems/win32/win32k/objects/gdiobj.c
subsystems/win32/win32k/objects/region.c

Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 6e88f53,0000000..879bd53
mode 100644,000000..100644
--- /dev/null
@@@ -1,1431 -1,0 +1,1431 @@@
- ;@ stdcall LdrEnumerateLoadedModules
 +
 +;@ stdcall A_SHAFinal ; 6.0 and higher
 +;@ stdcall A_SHAInit ; 6.0 and higher
 +;@ stdcall A_SHAUpdate ; 6.0 and higher
 +;@ stdcall AitFireParentUsageEvent ; 6.1 and higher
 +;@ stdcall AitLogFeatureUsageByApp ; 6.1 and higher
 +;@ stdcall AlpcAdjustCompletionListConcurrencyCount ; 6.0 and higher
 +;@ stdcall AlpcFreeCompletionListMessage ; 6.0 and higher
 +;@ stdcall AlpcGetCompletionListLastMessageInformation ; 6.0 and higher
 +;@ stdcall AlpcGetCompletionListMessageAttributes ; 6.0 and higher
 +;@ stdcall AlpcGetHeaderSize ; 6.0 and higher
 +;@ stdcall AlpcGetMessageAttribute ; 6.0 and higher
 +;@ stdcall AlpcGetMessageFromCompletionList ; 6.0 and higher
 +;@ stdcall AlpcGetOutstandingCompletionListMessageCount ; 6.0 and higher
 +;@ stdcall AlpcInitializeMessageAttribute ; 6.0 and higher
 +;@ stdcall AlpcMaxAllowedMessageLength ; 6.0 and higher
 +;@ stdcall AlpcRegisterCompletionList ; 6.0 and higher
 +;@ stdcall AlpcRegisterCompletionListWorkerThread ; 6.0 and higher
 +;@ stdcall AlpcRundownCompletionList ; 6.1 and higher
 +;@ stdcall AlpcUnregisterCompletionList ; 6.0 and higher
 +;@ stdcall AlpcUnregisterCompletionListWorkerThread ; 6.0 and higher
 +@ stdcall CsrAllocateCaptureBuffer(long long)
 +;@ stdcall CsrAllocateCapturePointer ; NT3, NT4 only
 +@ stdcall CsrAllocateMessagePointer(ptr long ptr)
 +@ stdcall CsrCaptureMessageBuffer(ptr ptr long ptr)
 +@ stdcall CsrCaptureMessageMultiUnicodeStringsInPlace(ptr long ptr)
 +@ stdcall CsrCaptureMessageString(ptr str long long ptr)
 +@ stdcall CsrCaptureTimeout(long ptr)
 +@ stdcall CsrClientCallServer(ptr ptr long long)
 +@ stdcall CsrClientConnectToServer(str long ptr ptr ptr)
 +;@ stdcall CsrClientMaxMessage ; NT3 only
 +;@ stdcall CsrClientSendMessage ; NT3 only
 +;@ stdcall CsrClientThreadConnect ; NT3 only
 +@ stdcall CsrFreeCaptureBuffer(ptr)
 +@ stdcall CsrGetProcessId()
 +@ stdcall CsrIdentifyAlertableThread()
 +@ stdcall CsrNewThread()
 +@ stdcall CsrProbeForRead(ptr long long)
 +@ stdcall CsrProbeForWrite(ptr long long)
 +@ stdcall CsrSetPriorityClass(ptr ptr)
 +;@ stdcall CsrpProcessCallbackRequest ; 3.51 only
 +@ stdcall DbgBreakPoint()
 +@ varargs DbgPrint(str)
 +@ varargs DbgPrintEx(long long str)
 +@ varargs DbgPrintReturnControlC(str)
 +@ stdcall DbgPrompt(ptr ptr long)
 +@ stdcall DbgQueryDebugFilterState(long long)
 +@ stdcall DbgSetDebugFilterState(long long long)
 +@ stdcall DbgUiConnectToDbg()
 +@ stdcall DbgUiContinue(ptr long)
 +@ stdcall DbgUiConvertStateChangeStructure(ptr ptr)
 +@ stdcall DbgUiDebugActiveProcess(ptr)
 +@ stdcall DbgUiGetThreadDebugObject()
 +@ stdcall DbgUiIssueRemoteBreakin(ptr)
 +@ stdcall DbgUiRemoteBreakin()
 +@ stdcall DbgUiSetThreadDebugObject(ptr)
 +@ stdcall DbgUiStopDebugging(ptr)
 +@ stdcall DbgUiWaitStateChange(ptr ptr)
 +@ stdcall DbgUserBreakPoint()
 +@ stdcall -arch=i386 KiFastSystemCall()
 +@ stdcall -arch=i386 KiFastSystemCallRet()
 +@ stdcall -arch=i386 KiIntSystemCall()
 +@ stdcall -arch=i386 ExpInterlockedPopEntrySListEnd()
 +@ stdcall -arch=i386 ExpInterlockedPopEntrySListFault()
 +@ stdcall -arch=i386 ExpInterlockedPopEntrySListResume()
 +@ stdcall KiRaiseUserExceptionDispatcher()
 +@ stdcall KiUserApcDispatcher(ptr ptr ptr ptr)
 +@ stdcall KiUserCallbackDispatcher(ptr ptr long) ; CHECKME
 +@ stdcall KiUserExceptionDispatcher(ptr ptr)
 +;@ stdcall LdrAccessOutOfProcessResource
 +@ stdcall LdrAccessResource(long ptr ptr ptr)
 +@ stdcall LdrAddRefDll(long ptr)
 +;@ stdcall LdrAlternateResourcesEnabled
 +;@ stdcall LdrCreateOutOfProcessImage
 +;@ stdcall LdrDestroyOutOfProcessImage
 +@ stdcall LdrDisableThreadCalloutsForDll(long)
 +@ stdcall LdrEnumResources(ptr ptr long ptr ptr)
++@ stdcall LdrEnumerateLoadedModules(long ptr long)
 +;@ stdcall LdrFindCreateProcessManifest ; 5.1 and 5.2 only
 +@ stdcall LdrFindEntryForAddress(ptr ptr)
 +@ stdcall LdrFindResourceDirectory_U(long ptr long ptr)
 +;@ stdcall LdrFindResourceEx_U ; 5.1 and higher
 +@ stdcall LdrFindResource_U(long ptr long ptr)
 +;@ stdcall LdrFlushAlternateResourceModules
 +@ stdcall LdrGetDllHandle(wstr long ptr ptr)
 +;@ stdcall LdrGetDllHandleEx
 +@ stdcall LdrGetProcedureAddress(ptr ptr long ptr)
 +;@ stdcall LdrHotPatchRoutine
 +;@ stdcall LdrInitShimEngineDynamic
 +@ stdcall LdrInitializeThunk(long long long long)
 +;@ stdcall LdrLoadAlternateResourceModule
 +@ stdcall LdrLoadDll(wstr long ptr ptr)
 +@ stdcall LdrLockLoaderLock(long ptr ptr)
 +;@ stdcall LdrOpenImageFileOptionsKey ; 5.2 SP1 and higher
 +@ stdcall LdrProcessRelocationBlock(ptr long ptr long)
 +@ stdcall LdrQueryImageFileExecutionOptions(ptr str long ptr long ptr)
 +@ stdcall LdrQueryProcessModuleInformation(ptr long ptr)
 +;@ stdcall LdrSetAppCompatDllRedirectionCallback
 +;@ stdcall LdrSetDllManifestProber
 +@ stdcall LdrShutdownProcess()
 +@ stdcall LdrShutdownThread()
 +@ stdcall LdrUnloadAlternateResourceModule(ptr)
 +@ stdcall LdrUnloadDll(ptr)
 +@ stdcall LdrUnlockLoaderLock(long long)
 +@ stdcall LdrVerifyImageMatchesChecksum(ptr long long long)
 +@ extern NlsAnsiCodePage
 +@ extern NlsMbCodePageTag
 +@ extern NlsMbOemCodePageTag
 +@ stdcall NtAcceptConnectPort(ptr long ptr long long ptr)
 +@ stdcall NtAccessCheck(ptr long long ptr ptr ptr ptr ptr)
 +@ stdcall NtAccessCheckAndAuditAlarm(ptr long ptr ptr ptr long ptr long ptr ptr ptr)
 +@ stdcall NtAccessCheckByType(ptr ptr ptr long ptr long ptr ptr long ptr ptr)
 +@ stdcall NtAccessCheckByTypeAndAuditAlarm(ptr ptr ptr ptr ptr ptr long long long ptr long ptr long ptr ptr ptr)
 +@ stdcall NtAccessCheckByTypeResultList(ptr ptr ptr long ptr long ptr ptr long ptr ptr)
 +@ stdcall NtAccessCheckByTypeResultListAndAuditAlarm(ptr ptr ptr ptr ptr ptr long long long ptr long ptr long ptr ptr ptr)
 +@ stdcall NtAccessCheckByTypeResultListAndAuditAlarmByHandle(ptr ptr ptr ptr ptr ptr ptr long long long ptr long ptr long ptr ptr ptr)
 +@ stdcall NtAddAtom(ptr long ptr)
 +@ stdcall NtAddBootEntry(ptr long)
 +@ stdcall NtAddDriverEntry(ptr long) ; 5.2 and higher
 +@ stdcall NtAdjustGroupsToken(long long ptr long ptr ptr)
 +@ stdcall NtAdjustPrivilegesToken(long long long long long long)
 +@ stdcall NtAlertResumeThread(long ptr)
 +@ stdcall NtAlertThread(long)
 +@ stdcall NtAllocateLocallyUniqueId(ptr)
 +@ stdcall NtAllocateUserPhysicalPages(ptr ptr ptr)
 +@ stdcall NtAllocateUuids(ptr ptr ptr ptr)
 +@ stdcall NtAllocateVirtualMemory(long ptr ptr ptr long long)
 +@ stdcall NtApphelpCacheControl(long ptr)
 +@ stdcall NtAreMappedFilesTheSame(ptr ptr)
 +@ stdcall NtAssignProcessToJobObject(long long)
 +@ stdcall NtCallbackReturn(ptr long long)
 +@ stdcall NtCancelDeviceWakeupRequest(ptr)
 +@ stdcall NtCancelIoFile(long ptr)
 +;@ stdcall NtCancelIoFileEx(long ptr ptr) ; 6.0 and higher
 +@ stdcall NtCancelTimer(long ptr)
 +@ stdcall NtClearEvent(long)
 +@ stdcall NtClose(long)
 +@ stdcall NtCloseObjectAuditAlarm(ptr ptr long)
 +@ stdcall NtCompactKeys(long ptr)
 +@ stdcall NtCompareTokens(ptr ptr ptr)
 +@ stdcall NtCompleteConnectPort(ptr)
 +@ stdcall NtCompressKey(ptr)
 +@ stdcall NtConnectPort(ptr ptr ptr ptr ptr ptr ptr ptr)
 +@ stdcall NtContinue(ptr long)
 +@ stdcall NtCreateDebugObject(ptr long ptr long)
 +@ stdcall NtCreateDirectoryObject(long long long)
 +@ stdcall NtCreateEvent(long long long long long)
 +@ stdcall NtCreateEventPair(ptr long ptr)
 +@ stdcall NtCreateFile(ptr long ptr ptr long long long ptr long long ptr)
 +@ stdcall NtCreateIoCompletion(ptr long ptr long)
 +@ stdcall NtCreateJobObject(ptr long ptr)
 +@ stdcall NtCreateJobSet(long ptr long)
 +@ stdcall NtCreateKey(ptr long ptr long ptr long long)
 +@ stdcall NtCreateKeyedEvent(ptr long ptr long)
 +@ stdcall NtCreateMailslotFile(long long long long long long long long)
 +@ stdcall NtCreateMutant(ptr long ptr long)
 +@ stdcall NtCreateNamedPipeFile(ptr long ptr ptr long long long long long long long long long ptr)
 +@ stdcall NtCreatePagingFile(long long long long)
 +@ stdcall NtCreatePort(ptr ptr long long ptr)
 +@ stdcall NtCreateProcess(ptr long ptr ptr long ptr ptr ptr)
 +@ stdcall NtCreateProcessEx(ptr long ptr ptr long ptr ptr ptr long)
 +@ stdcall NtCreateProfile(ptr ptr ptr long long ptr long long long) ; CHECKME
 +@ stdcall NtCreateSection(ptr long ptr ptr long long long)
 +@ stdcall NtCreateSemaphore(ptr long ptr long long)
 +@ stdcall NtCreateSymbolicLinkObject(ptr long ptr ptr)
 +@ stdcall NtCreateThread(ptr long ptr ptr ptr ptr ptr long)
 +@ stdcall NtCreateTimer(ptr long ptr long)
 +@ stdcall NtCreateToken(ptr long ptr long ptr ptr ptr ptr ptr ptr ptr ptr ptr)
 +@ stdcall NtCreateWaitablePort(ptr ptr long long long)
 +@ stdcall -arch=win32 NtCurrentTeb() _NtCurrentTeb
 +@ stdcall NtDebugActiveProcess(ptr ptr)
 +@ stdcall NtDebugContinue(ptr ptr long)
 +@ stdcall NtDelayExecution(long ptr)
 +@ stdcall NtDeleteAtom(long)
 +@ stdcall NtDeleteBootEntry(long)
 +@ stdcall NtDeleteFile(ptr)
 +@ stdcall NtDeleteKey(long)
 +@ stdcall NtDeleteObjectAuditAlarm(ptr ptr long)
 +@ stdcall NtDeleteValueKey(long ptr)
 +@ stdcall NtDeviceIoControlFile(long long long long long long long long long long)
 +@ stdcall NtDisplayString(ptr)
 +@ stdcall NtDuplicateObject(long long long ptr long long long)
 +@ stdcall NtDuplicateToken(long long long long long long)
 +@ stdcall NtEnumerateBootEntries(ptr ptr)
 +;@ stdcall NtEnumerateBus ; 3.51 only
 +@ stdcall NtEnumerateKey (long long long long long long)
 +@ stdcall NtEnumerateSystemEnvironmentValuesEx(long ptr long)
 +@ stdcall NtEnumerateValueKey(long long long long long long)
 +@ stdcall NtExtendSection(ptr ptr)
 +@ stdcall NtFilterToken(ptr long ptr ptr ptr ptr)
 +@ stdcall NtFindAtom(ptr long ptr)
 +@ stdcall NtFlushBuffersFile(long ptr)
 +@ stdcall NtFlushInstructionCache(long ptr long)
 +@ stdcall NtFlushKey(long)
 +@ stdcall NtFlushVirtualMemory(long ptr ptr long)
 +@ stdcall NtFlushWriteBuffer()
 +@ stdcall NtFreeUserPhysicalPages(ptr ptr ptr)
 +@ stdcall NtFreeVirtualMemory(long ptr ptr long)
 +@ stdcall NtFsControlFile(long long long long long long long long long long)
 +@ stdcall NtGetContextThread(long ptr)
 +@ stdcall NtGetCurrentProcessorNumber() ; 5.2 and higher
 +@ stdcall NtGetDevicePowerState(ptr ptr)
 +@ stdcall NtGetPlugPlayEvent(long long ptr long)
 +;@ stdcall NtGetTickCount()
 +@ stdcall NtGetWriteWatch(long long ptr long ptr ptr ptr)
 +@ stdcall NtImpersonateAnonymousToken(ptr)
 +@ stdcall NtImpersonateClientOfPort(ptr ptr)
 +@ stdcall NtImpersonateThread(ptr ptr ptr)
 +@ stdcall NtInitializeRegistry(long)
 +@ stdcall NtInitiatePowerAction (long long long long)
 +@ stdcall NtIsProcessInJob(long long)
 +@ stdcall NtIsSystemResumeAutomatic()
 +@ stdcall NtListenPort(ptr ptr)
 +@ stdcall NtLoadDriver(ptr)
 +@ stdcall NtLoadKey2(ptr ptr long)
 +@ stdcall NtLoadKey(ptr ptr)
 +@ stdcall NtLockFile(long long ptr ptr ptr ptr ptr ptr long long)
 +@ stdcall NtLockProductActivationKeys(ptr ptr)
 +@ stdcall NtLockRegistryKey(ptr)
 +@ stdcall NtLockVirtualMemory(long ptr ptr long)
 +@ stdcall NtMakePermanentObject(ptr)
 +@ stdcall NtMakeTemporaryObject(long)
 +@ stdcall NtMapUserPhysicalPages(ptr ptr ptr)
 +@ stdcall NtMapUserPhysicalPagesScatter(ptr ptr ptr)
 +@ stdcall NtMapViewOfSection(long long ptr long long ptr ptr long long long)
 +@ stdcall NtModifyBootEntry(ptr)
 +@ stdcall NtNotifyChangeDirectoryFile(long long ptr ptr ptr ptr long long long)
 +@ stdcall NtNotifyChangeKey(long long ptr ptr ptr long long ptr long long)
 +@ stdcall NtNotifyChangeMultipleKeys(ptr long ptr ptr ptr ptr ptr long long ptr long long)
 +@ stdcall NtOpenDirectoryObject(long long long)
 +@ stdcall NtOpenEvent(long long long)
 +@ stdcall NtOpenEventPair(ptr long ptr)
 +@ stdcall NtOpenFile(ptr long ptr ptr long long)
 +@ stdcall NtOpenIoCompletion(ptr long ptr)
 +@ stdcall NtOpenJobObject(ptr long ptr)
 +@ stdcall NtOpenKey(ptr long ptr)
 +@ stdcall NtOpenKeyedEvent(ptr long ptr)
 +@ stdcall NtOpenMutant(ptr long ptr)
 +@ stdcall NtOpenObjectAuditAlarm(ptr ptr ptr ptr ptr ptr long long ptr long long ptr)
 +@ stdcall NtOpenProcess(ptr long ptr ptr)
 +@ stdcall NtOpenProcessToken(long long ptr)
 +@ stdcall NtOpenProcessTokenEx(long long long ptr)
 +@ stdcall NtOpenSection(ptr long ptr)
 +@ stdcall NtOpenSemaphore(long long ptr)
 +@ stdcall NtOpenSymbolicLinkObject (ptr long ptr)
 +@ stdcall NtOpenThread(ptr long ptr ptr)
 +@ stdcall NtOpenThreadToken(long long long ptr)
 +@ stdcall NtOpenThreadTokenEx(long long long long ptr)
 +@ stdcall NtOpenTimer(ptr long ptr)
 +@ stdcall NtPlugPlayControl(ptr ptr long)
 +@ stdcall NtPowerInformation(long ptr long ptr long)
 +@ stdcall NtPrivilegeCheck(ptr ptr ptr)
 +@ stdcall NtPrivilegeObjectAuditAlarm(ptr ptr ptr long ptr long)
 +@ stdcall NtPrivilegedServiceAuditAlarm(ptr ptr ptr ptr long)
 +@ stdcall NtProtectVirtualMemory(long ptr ptr long ptr)
 +@ stdcall NtPulseEvent(long ptr)
 +@ stdcall NtQueryAttributesFile(ptr ptr)
 +@ stdcall NtQueryBootEntryOrder(ptr ptr)
 +@ stdcall NtQueryBootOptions(ptr ptr)
 +@ stdcall NtQueryDebugFilterState(long long)
 +@ stdcall NtQueryDefaultLocale(long ptr)
 +@ stdcall NtQueryDefaultUILanguage(ptr)
 +@ stdcall NtQueryDirectoryFile(long long ptr ptr ptr ptr long long long ptr long)
 +@ stdcall NtQueryDirectoryObject(long ptr long long long ptr ptr)
 +@ stdcall NtQueryEaFile(long ptr ptr long long ptr long ptr long)
 +@ stdcall NtQueryEvent(long long ptr long ptr)
 +@ stdcall NtQueryFullAttributesFile(ptr ptr)
 +@ stdcall NtQueryInformationAtom(long long ptr long ptr)
 +@ stdcall NtQueryInformationFile(long ptr ptr long long)
 +@ stdcall NtQueryInformationJobObject(long long ptr long ptr)
 +@ stdcall NtQueryInformationPort(ptr long ptr long ptr)
 +@ stdcall NtQueryInformationProcess(long long ptr long ptr)
 +@ stdcall NtQueryInformationThread(long long ptr long ptr)
 +@ stdcall NtQueryInformationToken(long long ptr long ptr)
 +@ stdcall NtQueryInstallUILanguage(ptr)
 +@ stdcall NtQueryIntervalProfile(long ptr)
 +@ stdcall NtQueryIoCompletion(long long ptr long ptr)
 +@ stdcall NtQueryKey (long long ptr long ptr)
 +@ stdcall NtQueryMultipleValueKey(long ptr long ptr long ptr)
 +@ stdcall NtQueryMutant(long long ptr long ptr)
 +@ stdcall NtQueryObject(long long long long long)
 +@ stdcall NtQueryOpenSubKeys(ptr ptr)
 +@ stdcall NtQueryPerformanceCounter(ptr ptr)
 +@ stdcall NtQueryPortInformationProcess()
 +@ stdcall NtQueryQuotaInformationFile(ptr ptr ptr long long ptr long ptr long)
 +@ stdcall NtQuerySection (long long long long long)
 +@ stdcall NtQuerySecurityObject (long long long long long)
 +@ stdcall NtQuerySemaphore (long long ptr long ptr)
 +@ stdcall NtQuerySymbolicLinkObject(long ptr ptr)
 +@ stdcall NtQuerySystemEnvironmentValue(ptr ptr long ptr)
 +@ stdcall NtQuerySystemEnvironmentValueEx(ptr ptr ptr ptr ptr)
 +@ stdcall NtQuerySystemInformation(long long long long)
 +@ stdcall NtQuerySystemTime(ptr)
 +@ stdcall NtQueryTimer(ptr long ptr long ptr)
 +@ stdcall NtQueryTimerResolution(long long long)
 +@ stdcall NtQueryValueKey(long long long long long long)
 +@ stdcall NtQueryVirtualMemory(long ptr long ptr long ptr)
 +@ stdcall NtQueryVolumeInformationFile(long ptr ptr long long)
 +@ stdcall NtQueueApcThread(long ptr long long long)
 +@ stdcall NtRaiseException(ptr ptr long)
 +@ stdcall NtRaiseHardError(long long long ptr long ptr)
 +@ stdcall NtReadFile(long long ptr ptr ptr ptr long ptr ptr)
 +@ stdcall NtReadFileScatter(long long ptr ptr ptr ptr long ptr ptr)
 +@ stdcall NtReadRequestData(ptr ptr long ptr long ptr)
 +@ stdcall NtReadVirtualMemory(long ptr ptr long ptr)
 +;@ stdcall NtRegisterNewDevice ; 3.51 only
 +@ stdcall NtRegisterThreadTerminatePort(ptr)
 +@ stdcall NtReleaseKeyedEvent(ptr ptr long ptr)
 +@ stdcall NtReleaseMutant(long ptr)
 +;@ stdcall NtReleaseProcessMutant ; 3.51 only
 +@ stdcall NtReleaseSemaphore(long long ptr)
 +@ stdcall NtRemoveIoCompletion(ptr ptr ptr ptr ptr)
 +@ stdcall NtRemoveProcessDebug(ptr ptr)
 +@ stdcall NtRenameKey(ptr ptr)
 +@ stdcall NtReplaceKey(ptr long ptr)
 +@ stdcall NtReplyPort(ptr ptr)
 +@ stdcall NtReplyWaitReceivePort(ptr ptr ptr ptr)
 +@ stdcall NtReplyWaitReceivePortEx(ptr ptr ptr ptr ptr)
 +@ stdcall NtReplyWaitReplyPort(ptr ptr)
 +@ stdcall NtRequestDeviceWakeup(ptr)
 +@ stdcall NtRequestPort(ptr ptr)
 +@ stdcall NtRequestWaitReplyPort(ptr ptr ptr)
 +@ stdcall NtRequestWakeupLatency(long)
 +@ stdcall NtResetEvent(long ptr)
 +@ stdcall NtResetWriteWatch(long ptr long)
 +@ stdcall NtRestoreKey(long long long)
 +@ stdcall NtResumeProcess(ptr)
 +@ stdcall NtResumeThread(long long)
 +@ stdcall NtSaveKey(long long)
 +@ stdcall NtSaveKeyEx(ptr ptr long)
 +@ stdcall NtSaveMergedKeys(ptr ptr ptr)
 +@ stdcall NtSecureConnectPort(ptr ptr ptr ptr ptr ptr ptr ptr ptr)
 +@ stdcall NtSetBootEntryOrder(ptr ptr)
 +@ stdcall NtSetBootOptions(ptr long)
 +@ stdcall NtSetContextThread(long ptr)
 +@ stdcall NtSetDebugFilterState(long long long)
 +@ stdcall NtSetDefaultHardErrorPort(ptr)
 +@ stdcall NtSetDefaultLocale(long long)
 +@ stdcall NtSetDefaultUILanguage(long)
 +@ stdcall NtSetEaFile(long ptr ptr long)
 +@ stdcall NtSetEvent(long long)
 +@ stdcall NtSetEventBoostPriority(ptr)
 +@ stdcall NtSetHighEventPair(ptr)
 +@ stdcall NtSetHighWaitLowEventPair(ptr)
 +;@ stdcall NtSetHighWaitLowThread ; 3.51 and 4.0 only
 +@ stdcall NtSetInformationDebugObject(ptr long ptr long ptr)
 +@ stdcall NtSetInformationFile(long long long long long)
 +@ stdcall NtSetInformationJobObject(long long ptr long)
 +@ stdcall NtSetInformationKey(long long ptr long)
 +@ stdcall NtSetInformationObject(long long ptr long)
 +@ stdcall NtSetInformationProcess(long long long long)
 +@ stdcall NtSetInformationThread(long long ptr long)
 +@ stdcall NtSetInformationToken(long long ptr long)
 +@ stdcall NtSetIntervalProfile(long long)
 +@ stdcall NtSetIoCompletion(ptr long ptr long long)
 +@ stdcall NtSetLdtEntries(long double long double) ; CHECKME
 +@ stdcall NtSetLowEventPair(ptr)
 +@ stdcall NtSetLowWaitHighEventPair(ptr)
 +;@ stdcall NtSetLowWaitHighThread ; 3.51 and 4.0 only
 +@ stdcall NtSetQuotaInformationFile(ptr ptr ptr long)
 +@ stdcall NtSetSecurityObject(long long ptr)
 +@ stdcall NtSetSystemEnvironmentValue(ptr ptr)
 +@ stdcall NtSetSystemEnvironmentValueEx(ptr ptr)
 +@ stdcall NtSetSystemInformation(long ptr long)
 +@ stdcall NtSetSystemPowerState(long long long)
 +@ stdcall NtSetSystemTime(ptr ptr)
 +@ stdcall NtSetThreadExecutionState(long ptr)
 +@ stdcall NtSetTimer(long ptr ptr ptr long long ptr)
 +@ stdcall NtSetTimerResolution(long long ptr)
 +@ stdcall NtSetUuidSeed(ptr)
 +@ stdcall NtSetValueKey(long long long long long long)
 +@ stdcall NtSetVolumeInformationFile(long ptr ptr long long)
 +@ stdcall NtShutdownSystem(long)
 +@ stdcall NtSignalAndWaitForSingleObject(long long long ptr)
 +@ stdcall NtStartProfile(ptr)
 +@ stdcall NtStopProfile(ptr)
 +@ stdcall NtSuspendProcess(ptr)
 +@ stdcall NtSuspendThread(long ptr)
 +@ stdcall NtSystemDebugControl(long ptr long ptr long ptr)
 +@ stdcall NtTerminateJobObject(long long)
 +@ stdcall NtTerminateProcess(long long)
 +@ stdcall NtTerminateThread(long long)
 +@ stdcall NtTestAlert()
 +@ stdcall NtTraceEvent(long long long ptr)
 +@ stdcall NtTranslateFilePath(ptr long ptr long)
 +@ stdcall NtUnloadDriver(ptr)
 +@ stdcall NtUnloadKey(long)
 +@ stdcall NtUnloadKeyEx(ptr ptr)
 +@ stdcall NtUnlockFile(long ptr ptr ptr ptr)
 +@ stdcall NtUnlockVirtualMemory(long ptr ptr long)
 +@ stdcall NtUnmapViewOfSection(long ptr)
 +@ stdcall NtVdmControl(long ptr)
 +;@ stdcall NtW32Call(long ptr long ptr ptr)
 +@ stdcall NtWaitForDebugEvent(ptr long ptr ptr)
 +@ stdcall NtWaitForKeyedEvent(ptr ptr long ptr)
 +@ stdcall NtWaitForMultipleObjects(long ptr long long ptr)
 +;@ stdcall NtWaitForProcessMutant ; 3.51 only
 +@ stdcall NtWaitForSingleObject(long long long)
 +@ stdcall NtWaitHighEventPair(ptr)
 +@ stdcall NtWaitLowEventPair(ptr)
 +@ stdcall NtWriteFile(long long ptr ptr ptr ptr long ptr ptr)
 +@ stdcall NtWriteFileGather(long long ptr ptr ptr ptr long ptr ptr)
 +@ stdcall NtWriteRequestData(ptr ptr long ptr long ptr)
 +@ stdcall NtWriteVirtualMemory(long ptr ptr long ptr)
 +@ stdcall NtYieldExecution()
 +;@ stdcall PfxFindPrefix
 +;@ stdcall PfxInitialize
 +;@ stdcall PfxInsertPrefix
 +;@ stdcall PfxRemovePrefix
 +;@ stdcall PropertyLengthAsVariant
 +;@ stdcall RtlAbortRXact
 +@ stdcall RtlAbsoluteToSelfRelativeSD(ptr ptr ptr)
 +@ stdcall RtlAcquirePebLock()
 +@ stdcall RtlAcquireResourceExclusive(ptr long)
 +@ stdcall RtlAcquireResourceShared(ptr long)
 +@ stdcall RtlAcquireSRWLockExclusive(ptr)
 +@ stdcall RtlAcquireSRWLockShared(ptr)
 +@ stdcall RtlActivateActivationContext(long ptr ptr)
 +;@ stdcall RtlActivateActivationContextEx
 +@ stdcall RtlActivateActivationContextUnsafeFast(ptr ptr)
 +@ stdcall RtlAddAccessAllowedAce(ptr long long ptr)
 +@ stdcall RtlAddAccessAllowedAceEx(ptr long long long ptr)
 +@ stdcall RtlAddAccessAllowedObjectAce(ptr long long long ptr ptr ptr)
 +@ stdcall RtlAddAccessDeniedAce(ptr long long ptr)
 +@ stdcall RtlAddAccessDeniedAceEx(ptr long long long ptr)
 +@ stdcall RtlAddAccessDeniedObjectAce(ptr long long long ptr ptr ptr)
 +@ stdcall RtlAddAce(ptr long long ptr long)
 +;@ stdcall RtlAddActionToRXact
 +@ stdcall RtlAddAtomToAtomTable(ptr wstr ptr)
 +;@ stdcall RtlAddAttributeActionToRXact
 +@ stdcall RtlAddAuditAccessAce(ptr long long ptr long long)
 +@ stdcall RtlAddAuditAccessAceEx(ptr long long long ptr long long)
 +@ stdcall RtlAddAuditAccessObjectAce(ptr long long long ptr ptr ptr long long)
 +;@ stdcall RtlAddCompoundAce
 +;@ stdcall RtlAddRange ; 5.0 and 5.1 only
 +@ stdcall -arch=x86_64 RtlAddFunctionTable(ptr long long)
 +@ stdcall RtlAddMandatoryAce(ptr long long long long ptr)
 +@ stdcall RtlAddRefActivationContext(ptr)
 +;@ stdcall RtlAddRefMemoryStream
 +@ stdcall RtlAddVectoredContinueHandler(long ptr)
 +@ stdcall RtlAddVectoredExceptionHandler(long ptr)
 +;@ stdcall RtlAddressInSectionTable
 +@ stdcall RtlAdjustPrivilege(long long long ptr)
 +@ stdcall RtlAllocateActivationContextStack(ptr) ; CHEKME
 +@ stdcall RtlAllocateAndInitializeSid(ptr long long long long long long long long long ptr)
 +@ stdcall RtlAllocateHandle(ptr ptr)
 +@ stdcall RtlAllocateHeap(ptr long ptr)
 +@ stdcall RtlAnsiCharToUnicodeChar(ptr)
 +@ stdcall RtlAnsiStringToUnicodeSize(ptr) RtlxAnsiStringToUnicodeSize
 +@ stdcall RtlAnsiStringToUnicodeString(ptr ptr long)
 +@ stdcall RtlAppendAsciizToString(ptr str)
 +;@ stdcall RtlAppendPathElement
 +@ stdcall RtlAppendStringToString(ptr ptr)
 +@ stdcall RtlAppendUnicodeStringToString(ptr ptr)
 +@ stdcall RtlAppendUnicodeToString(ptr wstr)
 +;@ stdcall RtlApplicationVerifierStop
 +;@ stdcall RtlApplyRXact
 +;@ stdcall RtlApplyRXactNoFlush
 +@ stdcall RtlAreAllAccessesGranted(long long)
 +@ stdcall RtlAreAnyAccessesGranted(long long)
 +@ stdcall RtlAreBitsClear(ptr long long)
 +@ stdcall RtlAreBitsSet(ptr long long)
 +;@ stdcall RtlAssert2
 +@ stdcall RtlAssert(ptr ptr long ptr)
 +;@ stdcall RtlCancelTimer
 +@ stdcall -register RtlCaptureContext(ptr)
 +@ stdcall RtlCaptureStackBackTrace(long long ptr ptr)
 +;@ stdcall RtlCaptureStackContext
 +@ stdcall RtlCharToInteger(ptr long ptr)
 +;@ stdcall RtlCheckForOrphanedCriticalSections
 +;@ stdcall RtlCheckProcessParameters
 +@ stdcall RtlCheckRegistryKey(long ptr)
 +@ stdcall RtlClearAllBits(ptr)
 +@ stdcall RtlClearBits(ptr long long)
 +;@ stdcall RtlCloneMemoryStream
 +;@ stdcall RtlClosePropertySet ; NT 4.0 only
 +;@ stdcall RtlCommitMemoryStream
 +@ stdcall RtlCompactHeap(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 RtlComputeCrc32(long ptr long)
 +;@ stdcall RtlComputeImportTableHash
 +;@ stdcall RtlComputePrivatizedDllName_U
 +;@ stdcall RtlConsoleMultiByteToUnicodeN
 +@ stdcall RtlConvertExclusiveToShared(ptr)
 +@ stdcall -arch=win32 -ret64 RtlConvertLongToLargeInteger(long)
 +;@ stdcall RtlConvertPropertyToVariant
 +@ stdcall RtlConvertSharedToExclusive(ptr)
 +@ stdcall RtlConvertSidToUnicodeString(ptr ptr long)
 +;@ stdcall RtlConvertToAutoInheritSecurityObject
 +;@ stdcall RtlConvertUiListToApiList
 +@ stdcall -arch=win32 -ret64 RtlConvertUlongToLargeInteger(long)
 +;@ stdcall RtlConvertVariantToProperty
 +@ stdcall RtlCopyLuid(ptr ptr)
 +@ stdcall RtlCopyLuidAndAttributesArray(long ptr ptr)
 +;@ stdcall RtlCopyMappedMemory
 +;@ stdcall RtlCopyMemoryStreamTo
 +;@ stdcall RtlCopyOutOfProcessMemoryStreamTo
 +;@ stdcall RtlCopyRangeList ; 5.0 and 5.1 only
 +@ stdcall RtlCopySecurityDescriptor(ptr ptr)
 +@ stdcall RtlCopySid(long ptr ptr)
 +@ stdcall RtlCopySidAndAttributesArray(long ptr long ptr ptr ptr ptr)
 +@ stdcall RtlCopyString(ptr ptr)
 +@ stdcall RtlCopyUnicodeString(ptr ptr)
 +@ stdcall RtlCreateAcl(ptr long long)
 +@ stdcall RtlCreateActivationContext(ptr ptr)
 +;@ stdcall RtlCreateAndSetSD
 +@ stdcall RtlCreateAtomTable(long ptr)
 +@ stdcall RtlCreateBootStatusDataFile()
 +@ stdcall RtlCreateEnvironment(long ptr)
 +@ stdcall RtlCreateHeap(long ptr long long ptr ptr)
 +@ stdcall RtlCreateProcessParameters(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr)
 +;@ stdcall RtlCreatePropertySet ; 4.0 only
 +@ stdcall RtlCreateQueryDebugBuffer(long long)
 +@ stdcall RtlCreateRegistryKey(long wstr)
 +@ stdcall RtlCreateSecurityDescriptor(ptr long)
 +@ stdcall RtlCreateSystemVolumeInformationFolder(ptr)
 +@ stdcall RtlCreateTagHeap(ptr long str str)
 +@ stdcall RtlCreateTimer(ptr ptr ptr ptr long long long)
 +@ stdcall RtlCreateTimerQueue(ptr)
 +@ stdcall RtlCreateUnicodeString(ptr wstr)
 +@ stdcall RtlCreateUnicodeStringFromAsciiz(ptr str)
 +@ stdcall RtlCreateUserProcess(ptr long ptr ptr ptr ptr long ptr ptr ptr)
 +;@ stdcall RtlCreateUserSecurityObject
 +@ stdcall RtlCreateUserThread(long ptr long ptr long long ptr ptr ptr ptr)
 +@ stdcall RtlCustomCPToUnicodeN(ptr wstr long ptr str long)
 +@ stdcall RtlCutoverTimeToSystemTime(ptr ptr ptr long)
 +@ stdcall RtlDeNormalizeProcessParams(ptr)
 +@ stdcall RtlDeactivateActivationContext(long long)
 +@ stdcall RtlDeactivateActivationContextUnsafeFast(ptr)
 +;@ stdcall RtlDebugPrintTimes
 +@ stdcall RtlDecodePointer(ptr)
 +@ stdcall RtlDecodeSystemPointer(ptr) RtlEncodeSystemPointer
 +@ stdcall RtlDecompressBuffer(long ptr long ptr long ptr)
 +@ stdcall RtlDecompressFragment(long ptr long ptr long long ptr ptr)
 +;@ stdcall RtlDefaultNpAcl
 +@ stdcall RtlDelete(ptr)
 +@ stdcall RtlDeleteAce(ptr long)
 +@ stdcall RtlDeleteAtomFromAtomTable(ptr long)
 +@ stdcall RtlDeleteCriticalSection(ptr)
 +@ stdcall RtlDeleteElementGenericTable(ptr ptr)
 +@ stdcall RtlDeleteElementGenericTableAvl(ptr ptr)
 +@ cdecl -arch=x86_64 RtlDeleteFunctionTable(ptr)
 +@ stdcall RtlDeleteNoSplay(ptr ptr)
 +@ stdcall RtlDeleteOwnersRanges(ptr ptr)
 +@ stdcall RtlDeleteRange(ptr long long long long ptr)
 +@ stdcall RtlDeleteRegistryValue(long ptr ptr)
 +@ stdcall RtlDeleteResource(ptr)
 +@ stdcall RtlDeleteSecurityObject(ptr)
 +@ stdcall RtlDeleteTimer(ptr ptr ptr)
 +@ stdcall RtlDeleteTimerQueue(ptr)
 +@ stdcall RtlDeleteTimerQueueEx(ptr ptr)
 +@ stdcall RtlDeregisterWait(ptr)
 +@ stdcall RtlDeregisterWaitEx(ptr ptr)
 +@ stdcall RtlDestroyAtomTable(ptr)
 +@ stdcall RtlDestroyEnvironment(ptr)
 +@ stdcall RtlDestroyHandleTable(ptr)
 +@ stdcall RtlDestroyHeap(long)
 +@ stdcall RtlDestroyProcessParameters(ptr)
 +@ stdcall RtlDestroyQueryDebugBuffer(ptr)
 +@ stdcall RtlDetermineDosPathNameType_U(wstr)
 +@ stdcall RtlDllShutdownInProgress()
 +@ stdcall RtlDnsHostNameToComputerName(ptr ptr long)
 +@ stdcall RtlDoesFileExists_U(wstr)
 +;@ stdcall RtlDosApplyFileIsolationRedirection_Ustr
 +@ stdcall RtlDosPathNameToNtPathName_U(wstr ptr ptr ptr)
 +;@ stdcall RtlDosPathNameToNtPathName_U_WithStatus ; 5.2 SP1, and higher
 +@ stdcall RtlDosPathNameToRelativeNtPathName_U(ptr ptr ptr ptr) ; CHECKME
 +;@ stdcall RtlDosPathNameToRelativeNtPathName_U_WithStatus
 +@ stdcall RtlDosSearchPath_U(wstr wstr wstr long ptr ptr)
 +;@ stdcall RtlDosSearchPath_Ustr
 +@ stdcall RtlDowncaseUnicodeChar(long)
 +@ stdcall RtlDowncaseUnicodeString(ptr ptr long)
 +@ stdcall RtlDumpResource(ptr)
 +@ stdcall RtlDuplicateUnicodeString(long ptr ptr)
 +@ stdcall RtlEmptyAtomTable(ptr long)
 +;@ stdcall RtlEnableEarlyCriticalSectionEventCreation
 +@ stdcall RtlEncodePointer(ptr)
 +@ stdcall RtlEncodeSystemPointer(ptr)
 +@ stdcall -arch=win32 -ret64 RtlEnlargedIntegerMultiply(long long)
 +@ stdcall -arch=win32 RtlEnlargedUnsignedDivide(double long ptr)
 +@ stdcall -arch=win32 -ret64 RtlEnlargedUnsignedMultiply(long long)
 +@ stdcall RtlEnterCriticalSection(ptr)
 +@ stdcall RtlEnumProcessHeaps(ptr ptr)
 +@ 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 RtlEnumerateProperties ; 4.0 only
 +@ stdcall RtlEqualComputerName(ptr ptr)
 +@ stdcall RtlEqualDomainName(ptr ptr)
 +@ stdcall RtlEqualLuid(ptr ptr)
 +@ stdcall RtlEqualPrefixSid(ptr ptr)
 +@ stdcall RtlEqualSid(long long)
 +@ stdcall RtlEqualString(ptr ptr long)
 +@ stdcall RtlEqualUnicodeString(ptr ptr long)
 +@ stdcall RtlEraseUnicodeString(ptr)
 +@ stdcall RtlExitUserThread(long)
 +@ stdcall RtlExpandEnvironmentStrings_U(ptr ptr ptr ptr)
 +@ stdcall RtlExtendHeap(ptr long ptr ptr)
 +@ stdcall -arch=win32 -ret64 RtlExtendedIntegerMultiply(double long)
 +@ stdcall -arch=win32 -ret64 RtlExtendedLargeIntegerDivide(double long ptr)
 +@ stdcall -arch=win32 -ret64 RtlExtendedMagicDivide(double double long)
 +@ stdcall RtlFillMemory(ptr long long)
 +@ stdcall RtlFillMemoryUlong(ptr long long)
 +;@ stdcall RtlFinalReleaseOutOfProcessMemoryStream
 +;@ stdcall RtlFindActivationContextSectionGuid
 +@ stdcall RtlFindActivationContextSectionString(long ptr long ptr ptr)
 +@ stdcall RtlFindCharInUnicodeString(long ptr ptr ptr)
 +@ stdcall RtlFindClearBits(ptr long long)
 +@ stdcall RtlFindClearBitsAndSet(ptr long long)
 +@ stdcall RtlFindClearRuns(ptr ptr long long)
 +@ stdcall RtlFindLastBackwardRunClear(ptr long ptr)
 +;@ stdcall RtlFindLastBackwardRunSet(ptr long ptr)
 +@ stdcall RtlFindLeastSignificantBit(double)
 +@ stdcall RtlFindLongestRunClear(ptr long)
 +@ stdcall RtlFindLongestRunSet(ptr long)
 +@ stdcall RtlFindMessage(long long long long ptr)
 +@ stdcall RtlFindMostSignificantBit(double)
 +@ stdcall RtlFindNextForwardRunClear(ptr long ptr)
 +;@ stdcall RtlFindNextForwardRunSet(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 RtlFindSetRuns(ptr ptr long long)
 +@ stdcall RtlFirstEntrySList(ptr)
 +@ stdcall RtlFirstFreeAce(ptr ptr)
 +;@ stdcall RtlFlushPropertySet ; 4.0 only
 +@ stdcall RtlFlushSecureMemoryCache(ptr ptr)
 +@ stdcall RtlFormatCurrentUserKeyPath(ptr)
 +@ stdcall RtlFormatMessage(ptr long long long long ptr ptr long)
 +;@ stdcall RtlFormatMessageEx
 +;@ stdcall RtlFreeActivationContextStack
 +@ stdcall RtlFreeAnsiString(long)
 +@ stdcall RtlFreeHandle(ptr ptr)
 +@ stdcall RtlFreeHeap(long long long)
 +@ stdcall RtlFreeOemString(ptr)
 +@ stdcall RtlFreeRangeList(ptr)
 +@ stdcall RtlFreeSid(long)
 +@ stdcall RtlFreeThreadActivationContextStack()
 +@ stdcall RtlFreeUnicodeString(ptr)
 +@ stdcall RtlFreeUserThreadStack(ptr ptr) ; 4.0 to 5.2 only
 +@ stdcall RtlGUIDFromString(ptr ptr)
 +@ stdcall RtlGenerate8dot3Name(ptr ptr long ptr)
 +@ stdcall RtlGetAce(ptr long ptr)
 +@ stdcall RtlGetActiveActivationContext(ptr)
 +@ stdcall RtlGetCallersAddress(ptr ptr)
 +@ stdcall RtlGetCompressionWorkSpaceSize(long ptr ptr)
 +@ stdcall RtlGetControlSecurityDescriptor(ptr ptr ptr)
 +;@ stdcall RtlGetCriticalSectionRecursionCount
 +@ stdcall RtlGetCurrentDirectory_U(long ptr)
 +@ stdcall RtlGetCurrentPeb()
 +@ stdcall RtlGetCurrentProcessorNumber() ; 5.2 SP1 and higher
 +@ stdcall RtlGetDaclSecurityDescriptor(ptr ptr ptr ptr)
 +@ stdcall RtlGetElementGenericTable(ptr long)
 +@ stdcall RtlGetElementGenericTableAvl(ptr long)
 +@ stdcall RtlGetFirstRange(ptr ptr ptr)
 +;@ stdcall RtlGetFrame
 +@ stdcall RtlGetFullPathName_U(wstr long ptr ptr)
 +;@ stdcall RtlGetFullPathName_UstrEx
 +@ stdcall RtlGetGroupSecurityDescriptor(ptr ptr ptr)
 +@ stdcall RtlGetLastNtStatus()
 +@ stdcall RtlGetLastWin32Error()
 +;@ stdcall RtlGetLengthWithoutLastFullDosOrNtPathElement
 +; Yes, Microsoft really misspelled this one!
 +;@ stdcall RtlGetLengthWithoutTrailingPathSeperators
 +@ stdcall RtlGetLongestNtPathLength()
 +;@ stdcall RtlGetNativeSystemInformation
 +@ stdcall RtlGetNextRange(ptr ptr long)
 +@ stdcall RtlGetNtGlobalFlags()
 +@ stdcall RtlGetNtProductType(ptr)
 +@ stdcall RtlGetNtVersionNumbers(ptr ptr ptr)
 +@ stdcall RtlGetOwnerSecurityDescriptor(ptr ptr ptr)
 +;@ stdcall RtlGetProductInfo(long long long long ptr)
 +@ stdcall RtlGetProcessHeaps(long ptr)
 +@ stdcall RtlGetSaclSecurityDescriptor(ptr ptr ptr ptr)
 +@ stdcall RtlGetSecurityDescriptorRMControl(ptr ptr)
 +@ stdcall RtlGetSetBootStatusData(ptr long long ptr long long)
 +;@ stdcall RtlGetThreadErrorMode
 +;@ stdcall RtlGetUnloadEventTrace
 +@ stdcall RtlGetUserInfoHeap(ptr long ptr ptr ptr)
 +@ stdcall RtlGetVersion(ptr)
 +;@ stdcall RtlGuidToPropertySetName ; 4.0 only
 +@ stdcall RtlHashUnicodeString(ptr long long ptr)
 +@ stdcall RtlIdentifierAuthoritySid(ptr)
 +@ stdcall RtlImageDirectoryEntryToData(long long long ptr)
 +@ stdcall RtlImageNtHeader(long)
 +;@ stdcall RtlImageNtHeaderEx
 +@ stdcall RtlImageRvaToSection(ptr long long)
 +@ stdcall RtlImageRvaToVa(ptr long long ptr)
 +@ stdcall RtlImpersonateSelf(long)
 +@ stdcall RtlInitAnsiString(ptr str)
 +@ stdcall RtlInitAnsiStringEx(ptr str)
 +@ stdcall RtlInitCodePageTable(ptr ptr)
 +;@ stdcall RtlInitMemoryStream
 +@ stdcall RtlInitNlsTables(ptr ptr ptr ptr)
 +;@ stdcall RtlInitOutOfProcessMemoryStream
 +@ stdcall RtlInitString(ptr str)
 +@ stdcall RtlInitUnicodeString(ptr wstr)
 +@ stdcall RtlInitUnicodeStringEx(ptr wstr)
 +;@ stdcall RtlInitializeAtomPackage
 +@ stdcall RtlInitializeBitMap(ptr long long)
 +@ stdcall RtlInitializeContext(ptr ptr ptr ptr ptr)
 +@ stdcall RtlInitializeCriticalSection(ptr)
 +@ stdcall RtlInitializeCriticalSectionAndSpinCount(ptr long)
 +;@ stdcall RtlInitializeCriticalSectionEx(ptr long long)
 +@ stdcall RtlInitializeGenericTable(ptr ptr ptr ptr ptr)
 +@ stdcall RtlInitializeGenericTableAvl(ptr ptr ptr ptr ptr)
 +@ stdcall RtlInitializeHandleTable(long long ptr)
 +;@ stdcall RtlInitializeRXact
 +@ stdcall RtlInitializeRangeList(ptr)
 +@ stdcall RtlInitializeResource(ptr)
 +@ stdcall RtlInitializeSListHead(ptr)
 +@ stdcall RtlInitializeSid(ptr ptr long)
 +@ stdcall RtlInitializeSRWLock(ptr)
 +;@ stdcall RtlInitializeStackTraceDataBase ; 5.1 SP2 and SP3, and 5.2 only
 +@ stdcall RtlInsertElementGenericTable(ptr ptr long ptr)
 +@ stdcall RtlInsertElementGenericTableAvl(ptr ptr long ptr)
 +@ stdcall RtlInt64ToUnicodeString(double long ptr)
 +@ stdcall RtlIntegerToChar(long long long ptr)
 +@ stdcall RtlIntegerToUnicodeString(long long ptr)
 +;@ stdcall RtlInterlockedCompareExchange64
 +@ stdcall -arch=i386,x86_64 RtlInterlockedFlushSList(ptr)
 +@ stdcall -arch=i386,x86_64 RtlInterlockedPopEntrySList(ptr)
 +@ stdcall -arch=i386,x86_64 RtlInterlockedPushEntrySList(ptr ptr)
 +@ stdcall RtlInterlockedPushListSList(ptr ptr ptr long)
 +@ 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 RtlIsActivationContextActive(ptr)
 +;@ stdcall RtlIsCriticalSectionLocked
 +;@ stdcall RtlIsCriticalSectionLockedByThread
 +@ stdcall RtlIsDosDeviceName_U(wstr)
 +@ stdcall RtlIsGenericTableEmpty(ptr)
 +@ stdcall RtlIsGenericTableEmptyAvl(ptr)
 +@ stdcall RtlIsNameLegalDOS8Dot3(ptr ptr ptr)
 +@ stdcall RtlIsRangeAvailable(ptr long long long long long long ptr ptr ptr)
 +@ stdcall RtlIsTextUnicode(ptr long ptr)
 +@ stdcall RtlIsThreadWithinLoaderCallout()
 +@ stdcall RtlIsValidHandle(ptr ptr)
 +@ stdcall RtlIsValidIndexHandle(ptr long ptr)
 +@ stdcall -arch=win32 -ret64 RtlLargeIntegerAdd(double double)
 +@ stdcall -arch=win32 -ret64 RtlLargeIntegerArithmeticShift(double long)
 +@ stdcall -arch=win32 -ret64 RtlLargeIntegerDivide(double double ptr)
 +@ stdcall -arch=win32 -ret64 RtlLargeIntegerNegate(double)
 +@ stdcall -arch=win32 -ret64 RtlLargeIntegerShiftLeft(double long)
 +@ stdcall -arch=win32 -ret64 RtlLargeIntegerShiftRight(double long)
 +@ stdcall -arch=win32 -ret64 RtlLargeIntegerSubtract(double double)
 +@ stdcall RtlLargeIntegerToChar(ptr long long ptr)
 +@ stdcall RtlLeaveCriticalSection(ptr)
 +@ stdcall RtlLengthRequiredSid(long)
 +@ stdcall RtlLengthSecurityDescriptor(ptr)
 +@ stdcall RtlLengthSid(ptr)
 +@ stdcall RtlLocalTimeToSystemTime(ptr ptr)
 +@ stdcall RtlLockBootStatusData(ptr)
 +@ stdcall RtlLockHeap(long)
 +;@ stdcall RtlLockMemoryStreamRegion
 +;@ stdcall RtlLogStackBackTrace
 +@ stdcall RtlLookupAtomInAtomTable(ptr wstr ptr)
 +@ stdcall RtlLookupElementGenericTable(ptr ptr)
 +@ stdcall RtlLookupElementGenericTableAvl(ptr ptr)
 +@ stdcall -arch=x86_64 RtlLookupFunctionEntry(long ptr ptr)
 +@ stdcall RtlMakeSelfRelativeSD(ptr ptr ptr)
 +@ stdcall RtlMapGenericMask(long ptr)
 +;@ stdcall RtlMapSecurityErrorToNtStatus
 +@ stdcall RtlMergeRangeLists(ptr ptr ptr long)
 +@ stdcall RtlMoveMemory(ptr ptr long)
 +;@ stdcall RtlMultiAppendUnicodeStringBuffer
 +@ stdcall RtlMultiByteToUnicodeN(ptr long ptr ptr long)
 +@ stdcall RtlMultiByteToUnicodeSize(ptr str long)
 +;@ stdcall RtlNewInstanceSecurityObject
 +;@ stdcall RtlNewSecurityGrantedAccess
 +@ stdcall RtlNewSecurityObject(ptr ptr ptr long ptr ptr)
 +;@ stdcall RtlNewSecurityObjectEx
 +;@ stdcall RtlNewSecurityObjectWithMultipleInheritance
 +@ stdcall RtlNormalizeProcessParams(ptr)
 +@ stdcall RtlNtPathNameToDosPathName(ptr ptr ptr ptr) ; CHECKME
 +@ stdcall RtlNtStatusToDosError(long)
 +@ stdcall RtlNtStatusToDosErrorNoTeb(long)
 +@ stdcall RtlNumberGenericTableElements(ptr)
 +@ stdcall RtlNumberGenericTableElementsAvl(ptr)
 +@ stdcall RtlNumberOfClearBits(ptr)
 +@ stdcall RtlNumberOfSetBits(ptr)
 +;@ stdcall RtlOemStringToUnicodeSize(ptr)
 +@ stdcall RtlOemStringToUnicodeString(ptr ptr long)
 +@ stdcall RtlOemToUnicodeN(ptr long ptr ptr long)
 +@ stdcall RtlOpenCurrentUser(long ptr)
 +@ stdcall RtlPcToFileHeader(ptr ptr)
 +@ stdcall RtlPinAtomInAtomTable(ptr long)
 +;@ stdcall RtlPopFrame
 +@ stdcall RtlPrefixString(ptr ptr long)
 +@ stdcall RtlPrefixUnicodeString(ptr ptr long)
 +;@ stdcall RtlPropertySetNameToGuid ; 4.0 only
 +@ stdcall RtlProtectHeap(ptr long)
 +;@ stdcall RtlPushFrame
 +@ stdcall RtlQueryAtomInAtomTable(ptr long ptr ptr ptr ptr)
 +@ stdcall RtlQueryDepthSList(ptr)
 +@ stdcall RtlQueryEnvironmentVariable_U(ptr ptr ptr)
 +@ stdcall RtlQueryHeapInformation(long long ptr long ptr)
 +@ stdcall RtlQueryInformationAcl(ptr ptr long long)
 +@ stdcall RtlQueryInformationActivationContext(long long ptr long ptr long ptr)
 +;@ stdcall RtlQueryInformationActiveActivationContext
 +;@ stdcall RtlQueryInterfaceMemoryStream
 +;@ stdcall RtlQueryProcessBackTraceInformation
 +@ stdcall RtlQueryProcessDebugInformation(long long ptr)
 +;@ stdcall RtlQueryProcessHeapInformation
 +;@ stdcall RtlQueryProcessLockInformation
 +;@ stdcall RtlQueryProperties ; 4.0 only
 +;@ stdcall RtlQueryPropertyNames ; 4.0 only
 +;@ stdcall RtlQueryPropertySet ; 4.0 only
 +@ stdcall RtlQueryRegistryValues(long ptr ptr ptr ptr)
 +@ stdcall RtlQuerySecurityObject(ptr long ptr long ptr)
 +@ stdcall RtlQueryTagHeap(ptr long long long ptr)
 +@ stdcall RtlQueryTimeZoneInformation(ptr)
 +;@ stdcall RtlQueueApcWow64Thread
 +@ stdcall RtlQueueWorkItem(ptr ptr long)
 +@ stdcall -register RtlRaiseException(ptr)
 +@ stdcall RtlRaiseStatus(long)
 +@ stdcall RtlRandom(ptr)
 +@ stdcall RtlRandomEx(ptr)
 +@ stdcall RtlReAllocateHeap(long long ptr long)
 +;@ stdcall RtlReadMemoryStream
 +;@ stdcall RtlReadOutOfProcessMemoryStream
 +@ stdcall RtlRealPredecessor(ptr)
 +@ stdcall RtlRealSuccessor(ptr)
 +@ stdcall RtlRegisterSecureMemoryCacheCallback(ptr)
 +@ stdcall RtlRegisterWait(ptr ptr ptr ptr long long)
 +@ stdcall RtlReleaseActivationContext(ptr)
 +;@ stdcall RtlReleaseMemoryStream
 +@ stdcall RtlReleasePebLock()
 +@ stdcall RtlReleaseResource(ptr)
 +@ stdcall RtlReleaseSRWLockExclusive(ptr)
 +@ stdcall RtlReleaseSRWLockShared(ptr)
 +@ stdcall RtlRemoteCall(ptr ptr ptr long ptr long long)
 +@ stdcall RtlRemoveVectoredContinueHandler(ptr)
 +@ stdcall RtlRemoveVectoredExceptionHandler(ptr)
 +@ stdcall RtlResetRtlTranslations(ptr)
 +@ stdcall RtlRestoreLastWin32Error(long) RtlSetLastWin32Error
 +;@ stdcall RtlRevertMemoryStream
 +@ stdcall RtlRunDecodeUnicodeString(long ptr)
 +@ stdcall RtlRunEncodeUnicodeString(long ptr)
 +@ stdcall RtlSecondsSince1970ToTime(long ptr)
 +@ stdcall RtlSecondsSince1980ToTime(long ptr)
 +;@ stdcall RtlSeekMemoryStream
 +@ stdcall RtlSelfRelativeToAbsoluteSD2(ptr ptr)
 +@ stdcall RtlSelfRelativeToAbsoluteSD(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr)
 +@ stdcall RtlSetAllBits(ptr)
 +@ stdcall RtlSetAttributesSecurityDescriptor(ptr long ptr)
 +@ stdcall RtlSetBits(ptr long long)
 +@ stdcall RtlSetControlSecurityDescriptor(ptr long long)
 +@ stdcall RtlSetCriticalSectionSpinCount(ptr long)
 +@ stdcall RtlSetCurrentDirectory_U(ptr)
 +@ stdcall RtlSetCurrentEnvironment(wstr ptr)
 +@ stdcall RtlSetDaclSecurityDescriptor(ptr long ptr long)
 +;@ stdcall RtlSetEnvironmentStrings
 +@ stdcall RtlSetEnvironmentVariable(ptr ptr ptr)
 +@ stdcall RtlSetGroupSecurityDescriptor(ptr ptr long)
 +@ stdcall RtlSetHeapInformation(ptr long ptr ptr)
 +@ stdcall RtlSetInformationAcl(ptr ptr long long)
 +@ stdcall RtlSetIoCompletionCallback(long ptr long)
 +@ stdcall RtlSetLastWin32Error(long)
 +@ stdcall RtlSetLastWin32ErrorAndNtStatusFromNtStatus(long)
 +;@ stdcall RtlSetMemoryStreamSize
 +@ stdcall RtlSetOwnerSecurityDescriptor(ptr ptr long)
 +@ stdcall RtlSetProcessIsCritical(long ptr long)
 +;@ stdcall RtlSetProperties ; RtlSetProperties
 +;@ stdcall RtlSetPropertyClassId ; 4.0 only
 +;@ stdcall RtlSetPropertyNames ; 4.0 only
 +;@ stdcall RtlSetPropertySetClassId ; 4.0 only
 +@ stdcall RtlSetSaclSecurityDescriptor(ptr long ptr long)
 +@ stdcall RtlSetSecurityDescriptorRMControl(ptr ptr)
 +@ stdcall RtlSetSecurityObject(long ptr ptr ptr ptr)
 +;@ stdcall RtlSetSecurityObjectEx
 +;@ stdcall RtlSetThreadErrorMode
 +;@ stdcall RtlSetThreadIsCritical
 +;@ stdcall RtlSetThreadPoolStartFunc
 +@ stdcall RtlSetTimeZoneInformation(ptr)
 +;@ stdcall RtlSetTimer
 +@ stdcall RtlSetUnhandledExceptionFilter(ptr)
 +;@ stdcall RtlSetUnicodeCallouts
 +@ stdcall RtlSetUserFlagsHeap(ptr long ptr long long)
 +@ stdcall RtlSetUserValueHeap(ptr long ptr ptr)
 +@ stdcall RtlSizeHeap(long long ptr)
 +@ stdcall RtlSleepConditionVariableCS(ptr ptr ptr)
 +@ stdcall RtlSleepConditionVariableSRW(ptr ptr ptr long)
 +@ stdcall RtlSplay(ptr)
 +;@ stdcall RtlStartRXact
 +;@ stdcall RtlStatMemoryStream
 +@ stdcall RtlStringFromGUID(ptr ptr)
 +@ stdcall RtlSubAuthorityCountSid(ptr)
 +@ stdcall RtlSubAuthoritySid(ptr long)
 +@ stdcall RtlSubtreePredecessor(ptr)
 +@ stdcall RtlSubtreeSuccessor(ptr)
 +@ stdcall RtlSystemTimeToLocalTime(ptr ptr)
 +@ stdcall RtlTimeFieldsToTime(ptr ptr)
 +@ stdcall RtlTimeToElapsedTimeFields(long long)
 +@ stdcall RtlTimeToSecondsSince1970(ptr ptr)
 +@ stdcall RtlTimeToSecondsSince1980(ptr ptr)
 +@ stdcall RtlTimeToTimeFields (long long)
 +;@ stdcall RtlTraceDatabaseAdd
 +;@ stdcall RtlTraceDatabaseCreate
 +;@ stdcall RtlTraceDatabaseDestroy
 +;@ stdcall RtlTraceDatabaseEnumerate
 +;@ stdcall RtlTraceDatabaseFind
 +;@ stdcall RtlTraceDatabaseLock
 +;@ stdcall RtlTraceDatabaseUnlock
 +;@ stdcall RtlTraceDatabaseValidate
 +@ stdcall RtlTryEnterCriticalSection(ptr)
 +@ fastcall -arch=i386 RtlUlongByteSwap(long)
 +@ fastcall -ret64 RtlUlonglongByteSwap(double)
 +;@ stdcall RtlUnhandledExceptionFilter2
 +@ stdcall RtlUnhandledExceptionFilter(ptr)
 +;@ stdcall RtlUnicodeStringToAnsiSize(ptr)
 +@ stdcall RtlUnicodeStringToAnsiString(ptr ptr long)
 +@ stdcall RtlUnicodeStringToCountedOemString(ptr ptr long)
 +@ stdcall RtlUnicodeStringToInteger(ptr long ptr)
 +;@ stdcall RtlUnicodeStringToOemSize(ptr)
 +@ stdcall RtlUnicodeStringToOemString(ptr ptr long)
 +@ stdcall RtlUnicodeToCustomCPN(ptr ptr long ptr wstr long)
 +@ stdcall RtlUnicodeToMultiByteN(ptr long ptr ptr long)
 +@ stdcall RtlUnicodeToMultiByteSize(ptr ptr long)
 +@ stdcall RtlUnicodeToOemN(ptr long ptr ptr long)
 +@ stdcall RtlUniform(ptr)
 +@ stdcall RtlUnlockBootStatusData(ptr)
 +@ stdcall RtlUnlockHeap(long)
 +;@ stdcall RtlUnlockMemoryStreamRegion
 +@ stdcall -register RtlUnwind(ptr ptr ptr ptr)
 +@ stdcall -arch=x86_64 RtlUnwindEx(long long ptr long 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 ptr long)
 +@ stdcall RtlUpcaseUnicodeToOemN(ptr long ptr ptr long)
 +@ stdcall RtlUpdateTimer(ptr ptr long long)
 +@ stdcall RtlUpperChar(long)
 +@ stdcall RtlUpperString(ptr ptr)
 +@ stdcall RtlUsageHeap(ptr long ptr)
 +@ fastcall -arch=i386 RtlUshortByteSwap(long)
 +@ stdcall RtlValidAcl(ptr)
 +@ stdcall RtlValidRelativeSecurityDescriptor(ptr long long)
 +@ stdcall RtlValidSecurityDescriptor(ptr)
 +@ stdcall RtlValidSid(ptr)
 +@ stdcall RtlValidateHeap(long long ptr)
 +@ stdcall RtlValidateProcessHeaps()
 +@ stdcall RtlValidateUnicodeString(long ptr)
 +@ stdcall RtlVerifyVersionInfo(ptr long double)
 +@ stdcall -arch=x86_64 RtlVirtualUnwind(long long long ptr ptr ptr ptr ptr)
 +@ stdcall RtlWalkFrameChain(ptr long long)
 +@ stdcall RtlWalkHeap(long ptr)
 +;@ stdcall RtlWow64EnableFsRedirection(long)
 +;@ stdcall RtlWow64EnableFsRedirectionEx(long ptr)
 +@ stdcall RtlWakeAllConditionVariable(ptr)
 +@ stdcall RtlWakeConditionVariable(ptr)
 +;@ stdcall RtlWriteMemoryStream
 +@ stdcall RtlWriteRegistryValue(long ptr ptr long ptr long)
 +@ stdcall RtlZeroHeap(ptr long)
 +@ stdcall RtlZeroMemory(ptr long)
 +@ stdcall RtlZombifyActivationContext(ptr)
 +;@ stdcall RtlpApplyLengthFunction
 +@ stdcall RtlpEnsureBufferSize(ptr ptr ptr) ; CHECKME
 +;@ stdcall RtlpNotOwnerCriticalSection
 +@ stdcall RtlpNtCreateKey(ptr long ptr long ptr ptr)
 +@ stdcall RtlpNtEnumerateSubKey(ptr ptr long long)
 +@ stdcall RtlpNtMakeTemporaryKey(ptr)
 +@ stdcall RtlpNtOpenKey(ptr long ptr long)
 +@ stdcall RtlpNtQueryValueKey(ptr ptr ptr ptr long)
 +@ stdcall RtlpNtSetValueKey(ptr long ptr long)
 +@ stdcall RtlpUnWaitCriticalSection(ptr)
 +@ stdcall RtlpWaitForCriticalSection(ptr)
 +@ stdcall RtlxAnsiStringToUnicodeSize(ptr)
 +@ stdcall RtlxOemStringToUnicodeSize(ptr)
 +@ stdcall RtlxUnicodeStringToAnsiSize(ptr)
 +@ stdcall RtlxUnicodeStringToOemSize(ptr) ; RtlUnicodeStringToOemSize
 +@ stdcall -ret64 VerSetConditionMask(double long long)
 +@ stdcall ZwAcceptConnectPort(ptr long ptr long long ptr) NtAcceptConnectPort
 +@ stdcall ZwAccessCheck(ptr long long ptr ptr ptr ptr ptr) NtAccessCheck
 +@ stdcall ZwAccessCheckAndAuditAlarm(ptr long ptr ptr ptr long ptr long ptr ptr ptr) NtAccessCheckAndAuditAlarm
 +@ stdcall ZwAccessCheckByType(ptr ptr ptr long ptr long ptr ptr long ptr ptr) NtAccessCheckByType
 +@ stdcall ZwAccessCheckByTypeAndAuditAlarm(ptr ptr ptr ptr ptr ptr long long long ptr long ptr long ptr ptr ptr) NtAccessCheckByTypeAndAuditAlarm
 +@ stdcall ZwAccessCheckByTypeResultList(ptr ptr ptr long ptr long ptr ptr long ptr ptr) NtAccessCheckByTypeResultList
 +@ stdcall ZwAccessCheckByTypeResultListAndAuditAlarm(ptr ptr ptr ptr ptr ptr long long long ptr long ptr long ptr ptr ptr) NtAccessCheckByTypeResultListAndAuditAlarm
 +@ stdcall ZwAccessCheckByTypeResultListAndAuditAlarmByHandle(ptr ptr ptr ptr ptr ptr ptr long long long ptr long ptr long ptr ptr ptr) NtAccessCheckByTypeResultListAndAuditAlarmByHandle
 +@ stdcall ZwAddAtom(ptr long ptr) NtAddAtom
 +@ stdcall ZwAddBootEntry(ptr long)
 +@ stdcall ZwAdjustGroupsToken(long long long long long long) NtAdjustGroupsToken
 +@ stdcall ZwAdjustPrivilegesToken(long long long long long long) NtAdjustPrivilegesToken
 +@ stdcall ZwAlertResumeThread(long ptr) NtAlertResumeThread
 +@ stdcall ZwAlertThread(long) NtAlertThread
 +@ stdcall ZwAllocateLocallyUniqueId(ptr) NtAllocateLocallyUniqueId
 +@ stdcall ZwAllocateUserPhysicalPages(ptr ptr ptr)
 +@ stdcall ZwAllocateUuids(ptr ptr ptr ptr) NtAllocateUuids
 +@ stdcall ZwAllocateVirtualMemory(long ptr ptr ptr long long) NtAllocateVirtualMemory
 +@ stdcall ZwAreMappedFilesTheSame(ptr ptr) NtAreMappedFilesTheSame
 +@ stdcall ZwAssignProcessToJobObject(long long) NtAssignProcessToJobObject
 +@ stdcall ZwCallbackReturn(ptr long long)
 +@ stdcall ZwCancelDeviceWakeupRequest(ptr)
 +@ stdcall ZwCancelIoFile(long ptr) NtCancelIoFile
 +;@ stdcall ZwCancelIoFileEx(long ptr ptr) NtCancelIoFileEx
 +@ stdcall ZwCancelTimer(long ptr) NtCancelTimer
 +@ stdcall ZwClearEvent(long) NtClearEvent
 +@ stdcall ZwClose(long) NtClose
 +@ stdcall ZwCloseObjectAuditAlarm(ptr ptr long)
 +@ stdcall ZwCompactKeys(long ptr) NtCompactKeys
 +@ stdcall ZwCompareTokens(ptr ptr ptr) NtCompareTokens
 +@ stdcall ZwCompleteConnectPort(ptr) NtCompleteConnectPort
 +@ stdcall ZwCompressKey(ptr) NtCompressKey
 +@ stdcall ZwConnectPort(ptr ptr ptr ptr ptr ptr ptr ptr) NtConnectPort
 +@ stdcall ZwContinue(ptr long) NtContinue
 +@ stdcall ZwCreateDebugObject(ptr long ptr long) NtCreateDebugObject
 +@ stdcall ZwCreateDirectoryObject(long long long) NtCreateDirectoryObject
 +@ stdcall ZwCreateEvent(long long long long long) NtCreateEvent
 +@ stdcall ZwCreateEventPair(ptr long ptr) NtCreateEventPair
 +@ stdcall ZwCreateFile(ptr long ptr ptr long long long ptr long long ptr) NtCreateFile
 +@ stdcall ZwCreateIoCompletion(ptr long ptr long) NtCreateIoCompletion
 +@ stdcall ZwCreateJobObject(ptr long ptr) NtCreateJobObject
 +@ stdcall ZwCreateJobSet(long ptr long) NtCreateJobSet
 +@ stdcall ZwCreateKey(ptr long ptr long ptr long long) NtCreateKey
 +@ stdcall ZwCreateKeyedEvent(ptr long ptr long) NtCreateKeyedEvent
 +@ stdcall ZwCreateMailslotFile(long long long long long long long long) NtCreateMailslotFile
 +@ stdcall ZwCreateMutant(ptr long ptr long) NtCreateMutant
 +@ stdcall ZwCreateNamedPipeFile(ptr long ptr ptr long long long long long long long long long ptr) NtCreateNamedPipeFile
 +@ stdcall ZwCreatePagingFile(long long long long) NtCreatePagingFile
 +@ stdcall ZwCreatePort(ptr ptr long long long) NtCreatePort
 +@ stdcall ZwCreateProcess(ptr long ptr ptr long ptr ptr ptr)
 +@ stdcall ZwCreateProcessEx(ptr long ptr ptr long ptr ptr ptr long) NtCreateProcessEx
 +@ stdcall ZwCreateProfile(ptr ptr ptr long long ptr long long long) NtCreateProfile ; CHECKME
 +@ stdcall ZwCreateSection(ptr long ptr ptr long long long) NtCreateSection
 +@ stdcall ZwCreateSemaphore(ptr long ptr long long) NtCreateSemaphore
 +@ stdcall ZwCreateSymbolicLinkObject(ptr long ptr ptr) NtCreateSymbolicLinkObject
 +@ stdcall ZwCreateThread(ptr long ptr ptr ptr ptr ptr long)
 +@ stdcall ZwCreateTimer(ptr long ptr long) NtCreateTimer
 +@ stdcall ZwCreateToken(ptr long ptr long ptr ptr ptr ptr ptr ptr ptr ptr ptr)
 +@ stdcall ZwCreateWaitablePort(ptr ptr long long long) NtCreateWaitablePort
 +@ stdcall ZwDebugActiveProcess(ptr ptr) NtDebugActiveProcess
 +@ stdcall ZwDebugContinue(ptr ptr long) NtDebugContinue
 +@ stdcall ZwDelayExecution(long ptr) NtDelayExecution
 +@ stdcall ZwDeleteAtom(long) NtDeleteAtom
 +@ stdcall ZwDeleteBootEntry(long) NtDeleteBootEntry
 +@ stdcall ZwDeleteFile(ptr) NtDeleteFile
 +@ stdcall ZwDeleteKey(long) NtDeleteKey
 +@ stdcall ZwDeleteObjectAuditAlarm(ptr ptr long)
 +@ stdcall ZwDeleteValueKey(long ptr) NtDeleteValueKey
 +@ stdcall ZwDeviceIoControlFile(long long long long long long long long long long) NtDeviceIoControlFile
 +@ stdcall ZwDisplayString(ptr) NtDisplayString
 +@ stdcall ZwDuplicateObject(long long long ptr long long long) NtDuplicateObject
 +@ stdcall ZwDuplicateToken(long long long long long long) NtDuplicateToken
 +@ stdcall ZwEnumerateBootEntries(ptr ptr)
 +;@ stdcall ZwEnumerateBus ; 3.51 only
 +@ stdcall ZwEnumerateKey(long long long ptr long ptr) NtEnumerateKey
 +@ stdcall ZwEnumerateSystemEnvironmentValuesEx(long ptr long) NtEnumerateSystemEnvironmentValuesEx
 +@ stdcall ZwEnumerateValueKey(long long long ptr long ptr) NtEnumerateValueKey
 +@ stdcall ZwExtendSection(ptr ptr) NtExtendSection
 +@ stdcall ZwFilterToken(ptr long ptr ptr ptr ptr) NtFilterToken
 +@ stdcall ZwFindAtom(ptr long ptr) NtFindAtom
 +@ stdcall ZwFlushBuffersFile(long ptr) NtFlushBuffersFile
 +@ stdcall ZwFlushInstructionCache(long ptr long) NtFlushInstructionCache
 +@ stdcall ZwFlushKey(long) NtFlushKey
 +@ stdcall ZwFlushVirtualMemory(long ptr ptr long) NtFlushVirtualMemory
 +@ stdcall ZwFlushWriteBuffer()
 +@ stdcall ZwFreeUserPhysicalPages(ptr ptr ptr)
 +@ stdcall ZwFreeVirtualMemory(long ptr ptr long) NtFreeVirtualMemory
 +@ stdcall ZwFsControlFile(long long long long long long long long long long) NtFsControlFile
 +@ stdcall ZwGetContextThread(long ptr) NtGetContextThread
 +@ stdcall ZwGetCurrentProcessorNumber()
 +@ stdcall ZwGetDevicePowerState(ptr ptr)
 +@ stdcall ZwGetPlugPlayEvent(long long ptr long)
 +;@ stdcall ZwGetTickCount() NtGetTickCount
 +@ stdcall ZwGetWriteWatch(long long ptr long ptr ptr ptr) NtGetWriteWatch
 +@ stdcall ZwImpersonateAnonymousToken(ptr)
 +@ stdcall ZwImpersonateClientOfPort(ptr ptr) NtImpersonateClientOfPort
 +@ stdcall ZwImpersonateThread(ptr ptr ptr) NtImpersonateThread
 +@ stdcall ZwInitializeRegistry(long)
 +@ stdcall ZwInitiatePowerAction(long long long long) NtInitiatePowerAction
 +@ stdcall ZwIsProcessInJob(long long) NtIsProcessInJob
 +@ stdcall ZwIsSystemResumeAutomatic()
 +@ stdcall ZwListenPort(ptr ptr) NtListenPort
 +@ stdcall ZwLoadDriver(ptr) NtLoadDriver
 +@ stdcall ZwLoadKey2(ptr ptr long) NtLoadKey2
 +@ stdcall ZwLoadKey(ptr ptr) NtLoadKey
 +@ stdcall ZwLockFile(long long ptr ptr ptr ptr ptr ptr long long) NtLockFile
 +@ stdcall ZwLockProductActivationKeys(ptr ptr) NtLockProductActivationKeys
 +@ stdcall ZwLockRegistryKey(ptr) NtLockRegistryKey
 +@ stdcall ZwLockVirtualMemory(long ptr ptr long) NtLockVirtualMemory
 +@ stdcall ZwMakePermanentObject(ptr) NtMakePermanentObject
 +@ stdcall ZwMakeTemporaryObject(long) NtMakeTemporaryObject
 +@ stdcall ZwMapUserPhysicalPages(ptr ptr ptr)
 +@ stdcall ZwMapUserPhysicalPagesScatter(ptr ptr ptr)
 +@ stdcall ZwMapViewOfSection(long long ptr long long ptr ptr long long long) NtMapViewOfSection
 +@ stdcall ZwModifyBootEntry(ptr) NtModifyBootEntry
 +@ stdcall ZwNotifyChangeDirectoryFile(long long ptr ptr ptr ptr long long long) NtNotifyChangeDirectoryFile
 +@ stdcall ZwNotifyChangeKey(long long ptr ptr ptr long long ptr long long) NtNotifyChangeKey
 +@ stdcall ZwNotifyChangeMultipleKeys(ptr long ptr ptr ptr ptr ptr long long ptr long long) NtNotifyChangeMultipleKeys
 +@ stdcall ZwOpenDirectoryObject(long long long) NtOpenDirectoryObject
 +@ stdcall ZwOpenEvent(long long long) NtOpenEvent
 +@ stdcall ZwOpenEventPair(ptr long ptr) NtOpenEventPair
 +@ stdcall ZwOpenFile(ptr long ptr ptr long long) NtOpenFile
 +@ stdcall ZwOpenIoCompletion(ptr long ptr) NtOpenIoCompletion
 +@ stdcall ZwOpenJobObject(ptr long ptr) NtOpenJobObject
 +@ stdcall ZwOpenKey(ptr long ptr) NtOpenKey
 +@ stdcall ZwOpenKeyedEvent(ptr long ptr) NtOpenKeyedEvent
 +@ stdcall ZwOpenMutant(ptr long ptr) NtOpenMutant
 +@ stdcall ZwOpenObjectAuditAlarm(ptr ptr ptr ptr ptr ptr long long ptr long long ptr)
 +@ stdcall ZwOpenProcess(ptr long ptr ptr) NtOpenProcess
 +@ stdcall ZwOpenProcessToken(long long ptr) NtOpenProcessToken
 +@ stdcall ZwOpenProcessTokenEx(long long long ptr) NtOpenProcessTokenEx
 +@ stdcall ZwOpenSection(ptr long ptr) NtOpenSection
 +@ stdcall ZwOpenSemaphore(long long ptr) NtOpenSemaphore
 +@ stdcall ZwOpenSymbolicLinkObject (ptr long ptr) NtOpenSymbolicLinkObject
 +@ stdcall ZwOpenThread(ptr long ptr ptr) NtOpenThread
 +@ stdcall ZwOpenThreadToken(long long long ptr) NtOpenThreadToken
 +@ stdcall ZwOpenThreadTokenEx(long long long long ptr) NtOpenThreadTokenEx
 +@ stdcall ZwOpenTimer(ptr long ptr) NtOpenTimer
 +@ stdcall ZwPlugPlayControl(ptr ptr long)
 +@ stdcall ZwPowerInformation(long ptr long ptr long) NtPowerInformation
 +@ stdcall ZwPrivilegeCheck(ptr ptr ptr) NtPrivilegeCheck
 +@ stdcall ZwPrivilegeObjectAuditAlarm(ptr ptr ptr long ptr long)
 +@ stdcall ZwPrivilegedServiceAuditAlarm(ptr ptr ptr ptr long)
 +@ stdcall ZwProtectVirtualMemory(long ptr ptr long ptr) NtProtectVirtualMemory
 +@ stdcall ZwPulseEvent(long ptr) NtPulseEvent
 +@ stdcall ZwQueryAttributesFile(ptr ptr) NtQueryAttributesFile
 +@ stdcall ZwQueryBootEntryOrder(ptr ptr) NtQueryBootEntryOrder
 +@ stdcall ZwQueryBootOptions(ptr ptr) NtQueryBootOptions
 +@ stdcall ZwQueryDebugFilterState(long long) NtQueryDebugFilterState
 +@ stdcall ZwQueryDefaultLocale(long ptr) NtQueryDefaultLocale
 +@ stdcall ZwQueryDefaultUILanguage(ptr) NtQueryDefaultUILanguage
 +@ stdcall ZwQueryDirectoryFile(long long ptr ptr ptr ptr long long long ptr long) NtQueryDirectoryFile
 +@ stdcall ZwQueryDirectoryObject(long ptr long long long ptr ptr) NtQueryDirectoryObject
 +@ stdcall ZwQueryEaFile(long ptr ptr long long ptr long ptr long) NtQueryEaFile
 +@ stdcall ZwQueryEvent(long long ptr long ptr) NtQueryEvent
 +@ stdcall ZwQueryFullAttributesFile(ptr ptr) NtQueryFullAttributesFile
 +@ stdcall ZwQueryInformationAtom(long long ptr long ptr) NtQueryInformationAtom
 +@ stdcall ZwQueryInformationFile(long ptr ptr long long) NtQueryInformationFile
 +@ stdcall ZwQueryInformationJobObject(long long ptr long ptr) NtQueryInformationJobObject
 +@ stdcall ZwQueryInformationPort(ptr long ptr long ptr) NtQueryInformationPort
 +@ stdcall ZwQueryInformationProcess(long long ptr long ptr) NtQueryInformationProcess
 +@ stdcall ZwQueryInformationThread(long long ptr long ptr) NtQueryInformationThread
 +@ stdcall ZwQueryInformationToken(long long ptr long ptr) NtQueryInformationToken
 +@ stdcall ZwQueryInstallUILanguage(ptr) NtQueryInstallUILanguage
 +@ stdcall ZwQueryIntervalProfile(long ptr) NtQueryIntervalProfile
 +@ stdcall ZwQueryIoCompletion(long long ptr long ptr) NtQueryIoCompletion
 +@ stdcall ZwQueryKey(long long ptr long ptr) NtQueryKey
 +@ stdcall ZwQueryMultipleValueKey(long ptr long ptr long ptr) NtQueryMultipleValueKey
 +@ stdcall ZwQueryMutant(long long ptr long ptr) NtQueryMutant
 +@ stdcall ZwQueryObject(long long long long long) NtQueryObject
 +@ stdcall ZwQueryOpenSubKeys(ptr ptr) NtQueryOpenSubKeys
 +@ stdcall ZwQueryPerformanceCounter (long long) NtQueryPerformanceCounter
 +@ stdcall ZwQueryPortInformationProcess() NtQueryPortInformationProcess
 +@ stdcall ZwQueryQuotaInformationFile(ptr ptr ptr long long ptr long ptr long) NtQueryQuotaInformationFile
 +@ stdcall ZwQuerySection (long long long long long) NtQuerySection
 +@ stdcall ZwQuerySecurityObject (long long long long long) NtQuerySecurityObject
 +@ stdcall ZwQuerySemaphore (long long long long long) NtQuerySemaphore
 +@ stdcall ZwQuerySymbolicLinkObject(long ptr ptr) NtQuerySymbolicLinkObject
 +@ stdcall ZwQuerySystemEnvironmentValue(ptr ptr long ptr) NtQuerySystemEnvironmentValue
 +@ stdcall ZwQuerySystemEnvironmentValueEx(ptr ptr ptr ptr ptr) NtQuerySystemEnvironmentValueEx
 +@ stdcall ZwQuerySystemInformation(long long long long) NtQuerySystemInformation
 +@ stdcall ZwQuerySystemTime(ptr) NtQuerySystemTime
 +@ stdcall ZwQueryTimer(ptr long ptr long ptr) NtQueryTimer
 +@ stdcall ZwQueryTimerResolution(long long long) NtQueryTimerResolution
 +@ stdcall ZwQueryValueKey(long ptr long ptr long ptr) NtQueryValueKey
 +@ stdcall ZwQueryVirtualMemory(long ptr long ptr long ptr) NtQueryVirtualMemory
 +@ stdcall ZwQueryVolumeInformationFile(long ptr ptr long long) NtQueryVolumeInformationFile
 +@ stdcall ZwQueueApcThread(long ptr long long long) NtQueueApcThread
 +@ stdcall ZwRaiseException(ptr ptr long) NtRaiseException
 +@ stdcall ZwRaiseHardError(long long long ptr long ptr) NtRaiseHardError
 +@ stdcall ZwReadFile(long long ptr ptr ptr ptr long ptr ptr) NtReadFile
 +@ stdcall ZwReadFileScatter(long long ptr ptr ptr ptr long ptr ptr) NtReadFileScatter
 +@ stdcall ZwReadRequestData(ptr ptr long ptr long ptr) NtReadRequestData
 +@ stdcall ZwReadVirtualMemory(long ptr ptr long ptr) NtReadVirtualMemory
 +;@ stdcall ZwRegisterNewDevice ; 3.51 only
 +@ stdcall ZwRegisterThreadTerminatePort(ptr) NtRegisterThreadTerminatePort
 +@ stdcall ZwReleaseKeyedEvent(ptr ptr long ptr) NtReleaseKeyedEvent
 +@ stdcall ZwReleaseMutant(long ptr) NtReleaseMutant
 +;@ stdcall ZwReleaseProcessMutant ; 3.51 only
 +@ stdcall ZwReleaseSemaphore(long long ptr) NtReleaseSemaphore
 +@ stdcall ZwRemoveIoCompletion(ptr ptr ptr ptr ptr) NtRemoveIoCompletion
 +@ stdcall ZwRemoveProcessDebug(ptr ptr) NtRemoveProcessDebug
 +@ stdcall ZwRenameKey(ptr ptr) NtRenameKey
 +@ stdcall ZwReplaceKey(ptr long ptr) NtReplaceKey
 +@ stdcall ZwReplyPort(ptr ptr) NtReplyPort
 +@ stdcall ZwReplyWaitReceivePort(ptr ptr ptr ptr) NtReplyWaitReceivePort
 +@ stdcall ZwReplyWaitReceivePortEx(ptr ptr ptr ptr ptr)
 +@ stdcall ZwReplyWaitReplyPort(ptr ptr)
 +@ stdcall ZwRequestDeviceWakeup(ptr)
 +@ stdcall ZwRequestPort(ptr ptr)
 +@ stdcall ZwRequestWaitReplyPort(ptr ptr ptr)
 +@ stdcall ZwRequestWakeupLatency(long)
 +@ stdcall ZwResetEvent(long ptr)
 +@ stdcall ZwResetWriteWatch(long ptr long)
 +@ stdcall ZwRestoreKey(long long long)
 +@ stdcall ZwResumeProcess(ptr)
 +@ stdcall ZwResumeThread(long long)
 +@ stdcall ZwSaveKey(long long)
 +@ stdcall ZwSaveKeyEx(ptr ptr long)
 +@ stdcall ZwSaveMergedKeys(ptr ptr ptr)
 +@ stdcall ZwSecureConnectPort(ptr ptr ptr ptr ptr ptr ptr ptr ptr)
 +@ stdcall ZwSetBootEntryOrder(ptr ptr)
 +@ stdcall ZwSetBootOptions(ptr long)
 +@ stdcall ZwSetContextThread(long ptr)
 +@ stdcall ZwSetDebugFilterState(long long long)
 +@ stdcall ZwSetDefaultHardErrorPort(ptr)
 +@ stdcall ZwSetDefaultLocale(long long)
 +@ stdcall ZwSetDefaultUILanguage(long)
 +@ stdcall ZwSetEaFile(long ptr ptr long)
 +@ stdcall ZwSetEvent(long long)
 +@ stdcall ZwSetEventBoostPriority(ptr)
 +@ stdcall ZwSetHighEventPair(ptr)
 +@ stdcall ZwSetHighWaitLowEventPair(ptr)
 +;@ stdcall ZwSetHighWaitLowThread ; 3.51 and 4.0 only
 +@ stdcall ZwSetInformationDebugObject(ptr long ptr long ptr)
 +@ stdcall ZwSetInformationFile(long long long long long)
 +@ stdcall ZwSetInformationJobObject(long long ptr long)
 +@ stdcall ZwSetInformationKey(long long ptr long)
 +@ stdcall ZwSetInformationObject(long long ptr long)
 +@ stdcall ZwSetInformationProcess(long long long long)
 +@ stdcall ZwSetInformationThread(long long ptr long)
 +@ stdcall ZwSetInformationToken(long long ptr long)
 +@ stdcall ZwSetIntervalProfile(long long)
 +@ stdcall ZwSetIoCompletion(ptr long ptr long long)
 +@ stdcall ZwSetLdtEntries(long double long double) ; CHECKME
 +@ stdcall ZwSetLowEventPair(ptr)
 +@ stdcall ZwSetLowWaitHighEventPair(ptr)
 +;@ stdcall ZwSetLowWaitHighThread ; 3.51 and 4.0 only
 +@ stdcall ZwSetQuotaInformationFile(ptr ptr ptr long)
 +@ stdcall ZwSetSecurityObject(long long ptr)
 +@ stdcall ZwSetSystemEnvironmentValue(ptr ptr)
 +@ stdcall ZwSetSystemEnvironmentValueEx(ptr ptr)
 +@ stdcall ZwSetSystemInformation(long ptr long)
 +@ stdcall ZwSetSystemPowerState(long long long)
 +@ stdcall ZwSetSystemTime(ptr ptr)
 +@ stdcall ZwSetThreadExecutionState(long ptr)
 +@ stdcall ZwSetTimer(long ptr ptr ptr long long ptr)
 +@ stdcall ZwSetTimerResolution(long long ptr)
 +@ stdcall ZwSetUuidSeed(ptr)
 +@ stdcall ZwSetValueKey(long long long long long long)
 +@ stdcall ZwSetVolumeInformationFile(long ptr ptr long long)
 +@ stdcall ZwShutdownSystem(long)
 +@ stdcall ZwSignalAndWaitForSingleObject(long long long ptr)
 +@ stdcall ZwStartProfile(ptr)
 +@ stdcall ZwStopProfile(ptr)
 +@ stdcall ZwSuspendProcess(ptr)
 +@ stdcall ZwSuspendThread(long ptr)
 +@ stdcall ZwSystemDebugControl(long ptr long ptr long ptr)
 +@ stdcall ZwTerminateJobObject(long long)
 +@ stdcall ZwTerminateProcess(long long)
 +@ stdcall ZwTerminateThread(long long)
 +@ stdcall ZwTestAlert()
 +@ stdcall ZwTraceEvent(long long long ptr)
 +@ stdcall ZwTranslateFilePath(ptr long ptr long)
 +@ stdcall ZwUnloadDriver(ptr)
 +@ stdcall ZwUnloadKey(long)
 +@ stdcall ZwUnloadKeyEx(ptr ptr)
 +@ stdcall ZwUnlockFile(long ptr ptr ptr ptr)
 +@ stdcall ZwUnlockVirtualMemory(long ptr ptr long)
 +@ stdcall ZwUnmapViewOfSection(long ptr)
 +@ stdcall ZwVdmControl(long ptr)
 +;@ stdcall ZwW32Call(long ptr long ptr ptr)
 +@ stdcall ZwWaitForDebugEvent(ptr long ptr ptr)
 +@ stdcall ZwWaitForKeyedEvent(ptr ptr long ptr)
 +@ stdcall ZwWaitForMultipleObjects(long ptr long long ptr)
 +;@ stdcall ZwWaitForProcessMutant ; 3.51 only
 +@ stdcall ZwWaitForSingleObject(long long long)
 +@ stdcall ZwWaitHighEventPair(ptr)
 +@ stdcall ZwWaitLowEventPair(ptr)
 +@ stdcall ZwWriteFile(long long ptr ptr ptr ptr long ptr ptr)
 +@ stdcall ZwWriteFileGather(long long ptr ptr ptr ptr long ptr ptr)
 +@ stdcall ZwWriteRequestData(ptr ptr long ptr long ptr)
 +@ stdcall ZwWriteVirtualMemory(long ptr ptr long ptr)
 +@ stdcall ZwYieldExecution()
 +;@ cdecl _CIcos
 +;@ cdecl _CIlog
 +;@ cdecl -private -arch=i386 _CIpow()
 +;@ cdecl _CIsin
 +;@ cdecl _CIsqrt
 +;@ stdcall -arch=x86_64 __C_specific_handler(ptr long ptr ptr)
 +@ cdecl __isascii(long)
 +@ cdecl __iscsym(long)
 +@ cdecl __iscsymf(long)
 +@ cdecl __toascii(long)
 +@ cdecl -arch=i386 -ret64 _alldiv(double double)
 +@ cdecl -arch=i386 _alldvrm()
 +@ cdecl -arch=i386 -ret64 _allmul(double double)
 +@ cdecl -arch=i386 -norelay _alloca_probe()
 +@ cdecl -arch=i386 -ret64 _allrem(double double)
 +@ cdecl -arch=i386 _allshl()
 +@ cdecl -arch=i386 _allshr()
 +@ cdecl -ret64 _atoi64(str)
 +@ cdecl -arch=i386 -ret64 _aulldiv(double double)
 +@ cdecl -arch=i386 _aulldvrm()
 +@ cdecl -arch=i386 -ret64 _aullrem(double double)
 +@ cdecl -arch=i386 _aullshr()
 +@ cdecl -arch=i386 -norelay _chkstk()
 +@ cdecl -arch=i386,x86_64 _fltused()
 +@ cdecl -arch=i386 -ret64 _ftol()
 +@ cdecl _i64toa(double ptr long)
 +@ cdecl _i64tow(double ptr long)
 +@ cdecl _itoa(long ptr long)
 +@ cdecl _itow(long ptr long)
 +@ cdecl _lfind(ptr ptr ptr long ptr)
 +@ cdecl _ltoa(long ptr long)
 +@ cdecl _ltow(long ptr long)
 +@ cdecl _memccpy(ptr ptr long long)
 +@ cdecl _memicmp(str str long)
 +@ cdecl -arch=x86_64 _setjmp(ptr ptr)
 +@ cdecl -arch=x86_64 _setjmpex(ptr ptr)
 +@ varargs _snprintf(ptr long str)
 +@ varargs _snwprintf(ptr long wstr)
 +@ cdecl _splitpath(str ptr ptr ptr ptr)
 +@ cdecl _strcmpi(str str) _stricmp
 +@ cdecl _stricmp(str str)
 +@ cdecl _strlwr(str)
 +@ cdecl _strnicmp(str str long)
 +@ cdecl _strupr(str)
 +@ cdecl _tolower(long)
 +@ cdecl _toupper(long)
 +@ cdecl _ui64toa(double ptr long)
 +@ cdecl _ui64tow(double ptr long)
 +@ cdecl _ultoa(long ptr long)
 +@ cdecl _ultow(long ptr long)
 +;@ cdecl _vscwprintf
 +@ cdecl _vsnprintf(ptr long str ptr)
 +@ cdecl _vsnwprintf(ptr long wstr ptr)
 +@ cdecl _wcsicmp(wstr wstr)
 +@ cdecl _wcslwr(wstr)
 +@ cdecl _wcsnicmp(wstr wstr long)
 +@ cdecl _wcsupr(wstr)
 +@ cdecl _wtoi(wstr)
 +@ cdecl _wtoi64(wstr)
 +@ cdecl _wtol(wstr)
 +@ cdecl abs(long)
 +@ cdecl -arch=i386,x86_64 atan(double)
 +@ cdecl atoi(str)
 +@ cdecl atol(str)
 +@ cdecl bsearch(ptr ptr long long ptr)
 +@ cdecl -arch=i386,x86_64 ceil(double)
 +@ cdecl -arch=i386,x86_64 cos(double)
 +@ cdecl -arch=i386,x86_64 fabs(double)
 +@ cdecl -arch=i386,x86_64 floor(double)
 +@ cdecl isalnum(long)
 +@ cdecl isalpha(long)
 +@ cdecl iscntrl(long)
 +@ cdecl isdigit(long)
 +@ cdecl isgraph(long)
 +@ cdecl islower(long)
 +@ cdecl isprint(long)
 +@ cdecl ispunct(long)
 +@ cdecl isspace(long)
 +@ cdecl isupper(long)
 +@ cdecl iswalpha(long)
 +@ cdecl iswctype(long long)
 +@ cdecl iswdigit(long)
 +@ cdecl iswlower(long)
 +@ cdecl iswspace(long)
 +@ cdecl iswxdigit(long)
 +@ cdecl isxdigit(long)
 +@ cdecl labs(long)
 +@ cdecl -arch=i386,x86_64 log(double)
 +@ cdecl -arch=x86_64 longjmp(ptr)
 +@ cdecl mbstowcs(ptr str long)
 +@ cdecl memchr(ptr long long)
 +@ cdecl memcmp(ptr ptr long)
 +@ cdecl memcpy(ptr ptr long) memmove
 +@ cdecl memmove(ptr ptr long)
 +@ cdecl memset(ptr long long)
 +@ cdecl -arch=i386,x86_64 pow(double double)
 +@ cdecl qsort(ptr long long ptr)
 +@ cdecl -arch=i386,x86_64 sin(double)
 +@ varargs sprintf(ptr str)
 +@ cdecl -arch=i386,x86_64 sqrt(double)
 +@ varargs sscanf(str str)
 +@ cdecl strcat(str str)
 +@ cdecl strchr(str long)
 +@ cdecl strcmp(str str)
 +@ cdecl strcpy(ptr str)
 +@ cdecl strcspn(str str)
 +@ cdecl strlen(str)
 +@ cdecl strncat(str str long)
 +@ cdecl strncmp(str str long)
 +@ cdecl strncpy(ptr str long)
 +@ cdecl strpbrk(str str)
 +@ cdecl strrchr(str long)
 +@ cdecl strspn(str str)
 +@ cdecl strstr(str str)
 +@ cdecl strtol(str ptr long)
 +@ cdecl strtoul(str ptr long)
 +@ varargs swprintf(ptr wstr)
 +@ cdecl -arch=i386,x86_64 tan(double)
 +@ cdecl tolower(long)
 +@ cdecl toupper(long)
 +@ cdecl towlower(long)
 +@ cdecl towupper(long)
 +@ stdcall vDbgPrintEx(long long str ptr)
 +@ stdcall vDbgPrintExWithPrefix(str long long str ptr)
 +@ cdecl vsprintf(ptr str ptr)
 +@ cdecl wcscat(wstr wstr)
 +@ cdecl wcschr(wstr long)
 +@ cdecl wcscmp(wstr wstr)
 +@ cdecl wcscpy(ptr wstr)
 +@ cdecl wcscspn(wstr wstr)
 +@ cdecl wcslen(wstr)
 +@ cdecl wcsncat(wstr wstr long)
 +@ cdecl wcsncmp(wstr wstr long)
 +@ cdecl wcsncpy(ptr wstr long)
 +@ cdecl wcspbrk(wstr wstr)
 +@ cdecl wcsrchr(wstr long)
 +@ cdecl wcsspn(wstr wstr)
 +@ cdecl wcsstr(wstr wstr)
 +;@ cdecl wcstok(wstr wstr)
 +@ cdecl wcstol(wstr ptr long)
 +@ cdecl wcstombs(ptr ptr long)
 +@ cdecl wcstoul(wstr ptr long)
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
index 3da2926,0000000..ce5a55f
mode 100644,000000..100644
--- /dev/null
@@@ -1,2182 -1,0 +1,2176 @@@
-       static HDC hScreenDC = 0;
 +/*
 + * Cursor and icon support
 + *
 + * Copyright 1995 Alexandre Julliard
 + *           1996 Martin Von Loewis
 + *           1997 Alex Korobka
 + *           1998 Turchanov Sergey
 + *           2007 Henri Verbeet
 + *
 + * 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
 + */
 +
 +#include <user32.h>
 +
 +#include <wine/debug.h>
 +
 +WINE_DEFAULT_DEBUG_CHANNEL(cursor);
 +WINE_DECLARE_DEBUG_CHANNEL(icon);
 +WINE_DECLARE_DEBUG_CHANNEL(resource);
 +
 +#include "pshpack1.h"
 +
 +typedef struct {
 +    BYTE bWidth;
 +    BYTE bHeight;
 +    BYTE bColorCount;
 +    BYTE bReserved;
 +    WORD xHotspot;
 +    WORD yHotspot;
 +    DWORD dwDIBSize;
 +    DWORD dwDIBOffset;
 +} CURSORICONFILEDIRENTRY;
 +
 +typedef struct
 +{
 +    WORD                idReserved;
 +    WORD                idType;
 +    WORD                idCount;
 +    CURSORICONFILEDIRENTRY  idEntries[1];
 +} CURSORICONFILEDIR;
 +
 +#include "poppack.h"
 +
 +static HDC screen_dc;
 +
 +static const WCHAR DISPLAYW[] = {'D','I','S','P','L','A','Y',0};
 +
 +
 +static CRITICAL_SECTION IconCrst;
 +static CRITICAL_SECTION_DEBUG critsect_debug =
 +{
 +    0, 0, &IconCrst,
 +    { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
 +      0, 0, { (DWORD_PTR)(__FILE__ ": IconCrst") }
 +};
 +static CRITICAL_SECTION IconCrst = { &critsect_debug, -1, 0, 0, 0, 0 };
 +
 +/***********************************************************************
 + *                            CreateCursorIconHandle
 + *
 + * Creates a handle with everything in there
 + */
 +static
 +HICON
 +CreateCursorIconHandle( PICONINFO IconInfo )
 +{
 +      HICON hIcon = (HICON)NtUserCallOneParam(0,
 +                                                                       ONEPARAM_ROUTINE_CREATEEMPTYCUROBJECT);
 +      if(!hIcon)
 +              return NULL;
 +
 +      NtUserSetCursorContents(hIcon, IconInfo);
 +      return hIcon;
 +}
 +
 +
 +
 +/***********************************************************************
 + *             map_fileW
 + *
 + * Helper function to map a file to memory:
 + *  name                      -       file name
 + *  [RETURN] ptr              -       pointer to mapped file
 + *  [RETURN] filesize           -       pointer size of file to be stored if not NULL
 + */
 +static void *map_fileW( LPCWSTR name, LPDWORD filesize )
 +{
 +    HANDLE hFile, hMapping;
 +    LPVOID ptr = NULL;
 +
 +    hFile = CreateFileW( name, GENERIC_READ, FILE_SHARE_READ, NULL,
 +                         OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, 0 );
 +    if (hFile != INVALID_HANDLE_VALUE)
 +    {
 +        hMapping = CreateFileMappingW( hFile, NULL, PAGE_READONLY, 0, 0, NULL );
 +        if (hMapping)
 +        {
 +            ptr = MapViewOfFile( hMapping, FILE_MAP_READ, 0, 0, 0 );
 +            CloseHandle( hMapping );
 +            if (filesize)
 +                *filesize = GetFileSize( hFile, NULL );
 +        }
 +        CloseHandle( hFile );
 +    }
 +    return ptr;
 +}
 +
 +
 +/***********************************************************************
 + *          get_dib_width_bytes
 + *
 + * Return the width of a DIB bitmap in bytes. DIB bitmap data is 32-bit aligned.
 + */
 +static int get_dib_width_bytes( int width, int depth )
 +{
 +    int words;
 +
 +    switch(depth)
 +    {
 +    case 1:  words = (width + 31) / 32; break;
 +    case 4:  words = (width + 7) / 8; break;
 +    case 8:  words = (width + 3) / 4; break;
 +    case 15:
 +    case 16: words = (width + 1) / 2; break;
 +    case 24: words = (width * 3 + 3)/4; break;
 +    default:
 +        WARN("(%d): Unsupported depth\n", depth );
 +        /* fall through */
 +    case 32:
 +        words = width;
 +    }
 +    return 4 * words;
 +}
 +
 +
 +/***********************************************************************
 + *           bitmap_info_size
 + *
 + * Return the size of the bitmap info structure including color table.
 + */
 +static int bitmap_info_size( const BITMAPINFO * info, WORD coloruse )
 +{
 +    unsigned int colors, size, masks = 0;
 +
 +    if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
 +    {
 +        const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)info;
 +        colors = (core->bcBitCount <= 8) ? 1 << core->bcBitCount : 0;
 +        return sizeof(BITMAPCOREHEADER) + colors *
 +             ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBTRIPLE) : sizeof(WORD));
 +    }
 +    else  /* assume BITMAPINFOHEADER */
 +    {
 +        colors = info->bmiHeader.biClrUsed;
 +        if (colors > 256) /* buffer overflow otherwise */
 +                colors = 256;
 +        if (!colors && (info->bmiHeader.biBitCount <= 8))
 +            colors = 1 << info->bmiHeader.biBitCount;
 +        if (info->bmiHeader.biCompression == BI_BITFIELDS) masks = 3;
 +        size = max( info->bmiHeader.biSize, sizeof(BITMAPINFOHEADER) + masks * sizeof(DWORD) );
 +        return size + colors * ((coloruse == DIB_RGB_COLORS) ? sizeof(RGBQUAD) : sizeof(WORD));
 +    }
 +}
 +
 +
 +/***********************************************************************
 + *          is_dib_monochrome
 + *
 + * Returns whether a DIB can be converted to a monochrome DDB.
 + *
 + * A DIB can be converted if its color table contains only black and
 + * white. Black must be the first color in the color table.
 + *
 + * Note : If the first color in the color table is white followed by
 + *        black, we can't convert it to a monochrome DDB with
 + *        SetDIBits, because black and white would be inverted.
 + */
 +static BOOL is_dib_monochrome( const BITMAPINFO* info )
 +{
 +    if (info->bmiHeader.biBitCount != 1) return FALSE;
 +
 +    if (info->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
 +    {
 +        const RGBTRIPLE *rgb = ((const BITMAPCOREINFO*)info)->bmciColors;
 +
 +        /* Check if the first color is black */
 +        if ((rgb->rgbtRed == 0) && (rgb->rgbtGreen == 0) && (rgb->rgbtBlue == 0))
 +        {
 +            rgb++;
 +
 +            /* Check if the second color is white */
 +            return ((rgb->rgbtRed == 0xff) && (rgb->rgbtGreen == 0xff)
 +                 && (rgb->rgbtBlue == 0xff));
 +        }
 +        else return FALSE;
 +    }
 +    else  /* assume BITMAPINFOHEADER */
 +    {
 +        const RGBQUAD *rgb = info->bmiColors;
 +
 +        /* Check if the first color is black */
 +        if ((rgb->rgbRed == 0) && (rgb->rgbGreen == 0) &&
 +            (rgb->rgbBlue == 0) && (rgb->rgbReserved == 0))
 +        {
 +            rgb++;
 +
 +            /* Check if the second color is white */
 +            return ((rgb->rgbRed == 0xff) && (rgb->rgbGreen == 0xff)
 +                 && (rgb->rgbBlue == 0xff) && (rgb->rgbReserved == 0));
 +        }
 +        else return FALSE;
 +    }
 +}
 +
 +/***********************************************************************
 + *           DIB_GetBitmapInfo
 + *
 + * Get the info from a bitmap header.
 + * Return 1 for INFOHEADER, 0 for COREHEADER,
 + */
 +static int DIB_GetBitmapInfo( const BITMAPINFOHEADER *header, LONG *width,
 +                              LONG *height, WORD *bpp, DWORD *compr )
 +{
 +    if (header->biSize == sizeof(BITMAPCOREHEADER))
 +    {
 +        const BITMAPCOREHEADER *core = (const BITMAPCOREHEADER *)header;
 +        *width  = core->bcWidth;
 +        *height = core->bcHeight;
 +        *bpp    = core->bcBitCount;
 +        *compr  = 0;
 +        return 0;
 +    }
 +    else if (header->biSize >= sizeof(BITMAPINFOHEADER))
 +    {
 +        *width  = header->biWidth;
 +        *height = header->biHeight;
 +        *bpp    = header->biBitCount;
 +        *compr  = header->biCompression;
 +        return 1;
 +    }
 +    ERR("(%d): unknown/wrong size for header\n", header->biSize );
 +    return -1;
 +}
 +
 +
 +/*
 + *  The following macro functions account for the irregularities of
 + *   accessing cursor and icon resources in files and resource entries.
 + */
 +typedef BOOL (*fnGetCIEntry)( LPVOID dir, int n,
 +                              int *width, int *height, int *bits );
 +
 +/**********************************************************************
 + *        CURSORICON_FindBestIcon
 + *
 + * Find the icon closest to the requested size and bit depth.
 + */
 +static int CURSORICON_FindBestIcon( LPVOID dir, fnGetCIEntry get_entry,
 +                                    int width, int height, int depth )
 +{
 +    int i, cx, cy, bits, bestEntry = -1;
 +    UINT iTotalDiff, iXDiff=0, iYDiff=0, iColorDiff;
 +    UINT iTempXDiff, iTempYDiff, iTempColorDiff;
 +
 +    /* Find Best Fit */
 +    iTotalDiff = 0xFFFFFFFF;
 +    iColorDiff = 0xFFFFFFFF;
 +    for ( i = 0; get_entry( dir, i, &cx, &cy, &bits ); i++ )
 +    {
 +        iTempXDiff = abs(width - cx);
 +        iTempYDiff = abs(height - cy);
 +
 +        if(iTotalDiff > (iTempXDiff + iTempYDiff))
 +        {
 +            iXDiff = iTempXDiff;
 +            iYDiff = iTempYDiff;
 +            iTotalDiff = iXDiff + iYDiff;
 +        }
 +    }
 +
 +    /* Find Best Colors for Best Fit */
 +    for ( i = 0; get_entry( dir, i, &cx, &cy, &bits ); i++ )
 +    {
 +        if(abs(width - cx) == iXDiff && abs(height - cy) == iYDiff)
 +        {
 +            iTempColorDiff = abs(depth - bits);
 +            if(iColorDiff > iTempColorDiff)
 +            {
 +                bestEntry = i;
 +                iColorDiff = iTempColorDiff;
 +            }
 +        }
 +    }
 +
 +    return bestEntry;
 +}
 +
 +static BOOL CURSORICON_GetResIconEntry( LPVOID dir, int n,
 +                                        int *width, int *height, int *bits )
 +{
 +    CURSORICONDIR *resdir = dir;
 +    ICONRESDIR *icon;
 +
 +    if ( resdir->idCount <= n )
 +        return FALSE;
 +    icon = &resdir->idEntries[n].ResInfo.icon;
 +    *width = icon->bWidth;
 +    *height = icon->bHeight;
 +    *bits = resdir->idEntries[n].wBitCount;
 +    return TRUE;
 +}
 +
 +/**********************************************************************
 + *        CURSORICON_FindBestCursor
 + *
 + * Find the cursor closest to the requested size.
 + *
 + * FIXME: parameter 'color' ignored.
 + */
 +static int CURSORICON_FindBestCursor( LPVOID dir, fnGetCIEntry get_entry,
 +                                      int width, int height, int depth )
 +{
 +    int i, maxwidth, maxheight, cx, cy, bits, bestEntry = -1;
 +
 +    /* Double height to account for AND and XOR masks */
 +
 +    height *= 2;
 +
 +    /* First find the largest one smaller than or equal to the requested size*/
 +
 +    maxwidth = maxheight = 0;
 +    for ( i = 0; get_entry( dir, i, &cx, &cy, &bits ); i++ )
 +    {
 +        if ((cx <= width) && (cy <= height) &&
 +            (cx > maxwidth) && (cy > maxheight))
 +        {
 +            bestEntry = i;
 +            maxwidth  = cx;
 +            maxheight = cy;
 +        }
 +    }
 +    if (bestEntry != -1) return bestEntry;
 +
 +    /* Now find the smallest one larger than the requested size */
 +
 +    maxwidth = maxheight = 255;
 +    for ( i = 0; get_entry( dir, i, &cx, &cy, &bits ); i++ )
 +    {
 +        if (((cx < maxwidth) && (cy < maxheight)) || (bestEntry == -1))
 +        {
 +            bestEntry = i;
 +            maxwidth  = cx;
 +            maxheight = cy;
 +        }
 +    }
 +
 +    return bestEntry;
 +}
 +
 +static BOOL CURSORICON_GetResCursorEntry( LPVOID dir, int n,
 +                                          int *width, int *height, int *bits )
 +{
 +    CURSORICONDIR *resdir = dir;
 +    CURSORDIR *cursor;
 +
 +    if ( resdir->idCount <= n )
 +        return FALSE;
 +    cursor = &resdir->idEntries[n].ResInfo.cursor;
 +    *width = cursor->wWidth;
 +    *height = cursor->wHeight;
 +    *bits = resdir->idEntries[n].wBitCount;
 +    return TRUE;
 +}
 +
 +static CURSORICONDIRENTRY *CURSORICON_FindBestIconRes( CURSORICONDIR * dir,
 +                                      int width, int height, int depth )
 +{
 +    int n;
 +
 +    n = CURSORICON_FindBestIcon( dir, CURSORICON_GetResIconEntry,
 +                                 width, height, depth );
 +    if ( n < 0 )
 +        return NULL;
 +    return &dir->idEntries[n];
 +}
 +
 +static CURSORICONDIRENTRY *CURSORICON_FindBestCursorRes( CURSORICONDIR *dir,
 +                                      int width, int height, int depth )
 +{
 +    int n = CURSORICON_FindBestCursor( dir, CURSORICON_GetResCursorEntry,
 +                                   width, height, depth );
 +    if ( n < 0 )
 +        return NULL;
 +    return &dir->idEntries[n];
 +}
 +
 +static BOOL CURSORICON_GetFileEntry( LPVOID dir, int n,
 +                                     int *width, int *height, int *bits )
 +{
 +    CURSORICONFILEDIR *filedir = dir;
 +    CURSORICONFILEDIRENTRY *entry;
 +    BITMAPINFOHEADER *info;
 +
 +    if ( filedir->idCount <= n )
 +        return FALSE;
 +    entry = &filedir->idEntries[n];
 +    /* FIXME: check against file size */
 +    info = (BITMAPINFOHEADER *)((char *)dir + entry->dwDIBOffset);
 +    *width = entry->bWidth;
 +    *height = entry->bHeight;
 +    *bits = info->biBitCount;
 +    return TRUE;
 +}
 +
 +static CURSORICONFILEDIRENTRY *CURSORICON_FindBestCursorFile( CURSORICONFILEDIR *dir,
 +                                      int width, int height, int depth )
 +{
 +    int n = CURSORICON_FindBestCursor( dir, CURSORICON_GetFileEntry,
 +                                       width, height, depth );
 +    if ( n < 0 )
 +        return NULL;
 +    return &dir->idEntries[n];
 +}
 +
 +static CURSORICONFILEDIRENTRY *CURSORICON_FindBestIconFile( CURSORICONFILEDIR *dir,
 +                                      int width, int height, int depth )
 +{
 +    int n = CURSORICON_FindBestIcon( dir, CURSORICON_GetFileEntry,
 +                                     width, height, depth );
 +    if ( n < 0 )
 +        return NULL;
 +    return &dir->idEntries[n];
 +}
 +
 +/***********************************************************************
 + *          create_icon_bitmaps
 + *
 + * Create the color, mask and alpha bitmaps from the DIB info.
 + */
 +static BOOL create_icon_bitmaps( const BITMAPINFO *bmi, int width, int height,
 +                                 HBITMAP *color, HBITMAP *mask )
 +{
 +    BOOL monochrome = is_dib_monochrome( bmi );
 +    unsigned int size = bitmap_info_size( bmi, DIB_RGB_COLORS );
 +    BITMAPINFO *info;
 +    void *color_bits, *mask_bits;
 +    BOOL ret = FALSE;
 +    HDC hdc = 0;
-       if(!hScreenDC)
-       {
-               hScreenDC = GetDC(0);
-               if(!hScreenDC) goto done;
-       }
-     if (!(hdc = CreateCompatibleDC(hScreenDC))) goto done;
 +
 +    if (!(info = HeapAlloc( GetProcessHeap(), 0, max( size, FIELD_OFFSET( BITMAPINFO, bmiColors[2] )))))
 +        return FALSE;
-         if (!(*color = CreateBitmap( width, height, GetDeviceCaps(hScreenDC, PLANES),
-                                      GetDeviceCaps(hScreenDC, BITSPIXEL), NULL )))
++    if (!(hdc = CreateCompatibleDC(NULL))) goto done;
 +
 +    memcpy( info, bmi, size );
 +    info->bmiHeader.biHeight /= 2;
 +
 +    color_bits = (char *)bmi + size;
 +    mask_bits = (char *)color_bits +
 +        get_dib_width_bytes( bmi->bmiHeader.biWidth,
 +                             bmi->bmiHeader.biBitCount ) * abs(info->bmiHeader.biHeight);
 +
 +    if (monochrome)
 +    {
 +        if (!(*mask = CreateBitmap( width, height * 2, 1, 1, NULL ))) goto done;
 +        *color = 0;
 +
 +        /* copy color data into second half of mask bitmap */
 +        SelectObject( hdc, *mask );
 +        StretchDIBits( hdc, 0, height, width, height,
 +                       0, 0, info->bmiHeader.biWidth, info->bmiHeader.biHeight,
 +                       color_bits, info, DIB_RGB_COLORS, SRCCOPY );
 +    }
 +    else
 +    {
 +        if (!(*mask = CreateBitmap( width, height, 1, 1, NULL ))) goto done;
++        if (!(*color = CreateBitmap( width, height, GetDeviceCaps(hdc, PLANES),
++                                     GetDeviceCaps(hdc, BITSPIXEL), NULL )))
 +        {
 +            DeleteObject( *mask );
 +            goto done;
 +        }
 +        SelectObject( hdc, *color );
 +        StretchDIBits( hdc, 0, 0, width, height,
 +                       0, 0, info->bmiHeader.biWidth, info->bmiHeader.biHeight,
 +                       color_bits, info, DIB_RGB_COLORS, SRCCOPY );
 +
 +        /* convert info to monochrome to copy the mask */
 +        info->bmiHeader.biBitCount = 1;
 +        if (info->bmiHeader.biSize != sizeof(BITMAPCOREHEADER))
 +        {
 +            RGBQUAD *rgb = info->bmiColors;
 +
 +            info->bmiHeader.biClrUsed = info->bmiHeader.biClrImportant = 2;
 +            rgb[0].rgbBlue = rgb[0].rgbGreen = rgb[0].rgbRed = 0x00;
 +            rgb[1].rgbBlue = rgb[1].rgbGreen = rgb[1].rgbRed = 0xff;
 +            rgb[0].rgbReserved = rgb[1].rgbReserved = 0;
 +        }
 +        else
 +        {
 +            RGBTRIPLE *rgb = (RGBTRIPLE *)(((BITMAPCOREHEADER *)info) + 1);
 +
 +            rgb[0].rgbtBlue = rgb[0].rgbtGreen = rgb[0].rgbtRed = 0x00;
 +            rgb[1].rgbtBlue = rgb[1].rgbtGreen = rgb[1].rgbtRed = 0xff;
 +        }
 +    }
 +
 +    SelectObject( hdc, *mask );
 +    StretchDIBits( hdc, 0, 0, width, height,
 +                   0, 0, info->bmiHeader.biWidth, info->bmiHeader.biHeight,
 +                   mask_bits, info, DIB_RGB_COLORS, SRCCOPY );
 +    ret = TRUE;
 +
 +done:
 +    if(hdc) DeleteDC( hdc );
 +    HeapFree( GetProcessHeap(), 0, info );
 +    return ret;
 +}
 +
 +static HICON CURSORICON_CreateIconFromBMI( BITMAPINFO *bmi,
 +                                         POINT hotspot, BOOL bIcon,
 +                                         DWORD dwVersion,
 +                                         INT width, INT height,
 +                                         UINT cFlag )
 +{
 +    HBITMAP color = 0, mask = 0;
 +    BOOL do_stretch;
 +      ICONINFO IconInfo;
 +
 +    if (dwVersion == 0x00020000)
 +    {
 +        FIXME_(cursor)("\t2.xx resources are not supported\n");
 +        return 0;
 +    }
 +
 +    /* Check bitmap header */
 +
 +    if ( (bmi->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)) &&
 +         (bmi->bmiHeader.biSize != sizeof(BITMAPINFOHEADER)  ||
 +          bmi->bmiHeader.biCompression != BI_RGB) )
 +    {
 +          WARN_(cursor)("\tinvalid resource bitmap header.\n");
 +          return 0;
 +    }
 +
 +    if (!width) width = bmi->bmiHeader.biWidth;
 +    if (!height) height = bmi->bmiHeader.biHeight/2;
 +    do_stretch = (bmi->bmiHeader.biHeight/2 != height) ||
 +                 (bmi->bmiHeader.biWidth != width);
 +
 +    /* Scale the hotspot */
 +    if (bIcon)
 +    {
 +        hotspot.x = width / 2;
 +        hotspot.y = height / 2;
 +    }
 +    else if (do_stretch)
 +    {
 +        hotspot.x = (hotspot.x * width) / bmi->bmiHeader.biWidth;
 +        hotspot.y = (hotspot.y * height) / (bmi->bmiHeader.biHeight / 2);
 +    }
 +
 +    if (!screen_dc) screen_dc = CreateDCW( DISPLAYW, NULL, NULL, NULL );
 +    if (!screen_dc) return 0;
 +
 +    if (!create_icon_bitmaps( bmi, width, height, &color, &mask )) return 0;
 +
 +      IconInfo.xHotspot = hotspot.x;
 +      IconInfo.yHotspot = hotspot.y;
 +      IconInfo.fIcon = bIcon;
 +      IconInfo.hbmColor = color;
 +      IconInfo.hbmMask = mask;
 +
 +      return CreateCursorIconHandle(&IconInfo);
 +}
 +
 +
 +/**********************************************************************
 + *          .ANI cursor support
 + */
 +#define RIFF_FOURCC( c0, c1, c2, c3 ) \
 +        ( (DWORD)(BYTE)(c0) | ( (DWORD)(BYTE)(c1) << 8 ) | \
 +        ( (DWORD)(BYTE)(c2) << 16 ) | ( (DWORD)(BYTE)(c3) << 24 ) )
 +
 +#define ANI_RIFF_ID RIFF_FOURCC('R', 'I', 'F', 'F')
 +#define ANI_LIST_ID RIFF_FOURCC('L', 'I', 'S', 'T')
 +#define ANI_ACON_ID RIFF_FOURCC('A', 'C', 'O', 'N')
 +#define ANI_anih_ID RIFF_FOURCC('a', 'n', 'i', 'h')
 +#define ANI_seq__ID RIFF_FOURCC('s', 'e', 'q', ' ')
 +#define ANI_fram_ID RIFF_FOURCC('f', 'r', 'a', 'm')
 +
 +#define ANI_FLAG_ICON       0x1
 +#define ANI_FLAG_SEQUENCE   0x2
 +
 +typedef struct {
 +    DWORD header_size;
 +    DWORD num_frames;
 +    DWORD num_steps;
 +    DWORD width;
 +    DWORD height;
 +    DWORD bpp;
 +    DWORD num_planes;
 +    DWORD display_rate;
 +    DWORD flags;
 +} ani_header;
 +
 +typedef struct {
 +    DWORD           data_size;
 +    const unsigned char   *data;
 +} riff_chunk_t;
 +
 +static void dump_ani_header( const ani_header *header )
 +{
 +    TRACE("     header size: %d\n", header->header_size);
 +    TRACE("          frames: %d\n", header->num_frames);
 +    TRACE("           steps: %d\n", header->num_steps);
 +    TRACE("           width: %d\n", header->width);
 +    TRACE("          height: %d\n", header->height);
 +    TRACE("             bpp: %d\n", header->bpp);
 +    TRACE("          planes: %d\n", header->num_planes);
 +    TRACE("    display rate: %d\n", header->display_rate);
 +    TRACE("           flags: 0x%08x\n", header->flags);
 +}
 +
 +
 +/*
 + * RIFF:
 + * DWORD "RIFF"
 + * DWORD size
 + * DWORD riff_id
 + * BYTE[] data
 + *
 + * LIST:
 + * DWORD "LIST"
 + * DWORD size
 + * DWORD list_id
 + * BYTE[] data
 + *
 + * CHUNK:
 + * DWORD chunk_id
 + * DWORD size
 + * BYTE[] data
 + */
 +static void riff_find_chunk( DWORD chunk_id, DWORD chunk_type, const riff_chunk_t *parent_chunk, riff_chunk_t *chunk )
 +{
 +    const unsigned char *ptr = parent_chunk->data;
 +    const unsigned char *end = parent_chunk->data + (parent_chunk->data_size - (2 * sizeof(DWORD)));
 +
 +    if (chunk_type == ANI_LIST_ID || chunk_type == ANI_RIFF_ID) end -= sizeof(DWORD);
 +
 +    while (ptr < end)
 +    {
 +        if ((!chunk_type && *(const DWORD *)ptr == chunk_id )
 +                || (chunk_type && *(const DWORD *)ptr == chunk_type && *((const DWORD *)ptr + 2) == chunk_id ))
 +        {
 +            ptr += sizeof(DWORD);
 +            chunk->data_size = (*(const DWORD *)ptr + 1) & ~1;
 +            ptr += sizeof(DWORD);
 +            if (chunk_type == ANI_LIST_ID || chunk_type == ANI_RIFF_ID) ptr += sizeof(DWORD);
 +            chunk->data = ptr;
 +
 +            return;
 +        }
 +
 +        ptr += sizeof(DWORD);
 +        ptr += (*(const DWORD *)ptr + 1) & ~1;
 +        ptr += sizeof(DWORD);
 +    }
 +}
 +
 +
 +/*
 + * .ANI layout:
 + *
 + * RIFF:'ACON'                  RIFF chunk
 + *     |- CHUNK:'anih'          Header
 + *     |- CHUNK:'seq '          Sequence information (optional)
 + *     \- LIST:'fram'           Frame list
 + *            |- CHUNK:icon     Cursor frames
 + *            |- CHUNK:icon
 + *            |- ...
 + *            \- CHUNK:icon
 + */
 +static HCURSOR CURSORICON_CreateIconFromANI( const LPBYTE bits, DWORD bits_size,
 +    INT width, INT height, INT depth )
 +{
 +    HCURSOR cursor;
 +    ani_header header = {0};
 +    LPBYTE frame_bits = 0;
 +    POINT hotspot;
 +    CURSORICONFILEDIRENTRY *entry;
 +
 +    riff_chunk_t root_chunk = { bits_size, bits };
 +    riff_chunk_t ACON_chunk = {0};
 +    riff_chunk_t anih_chunk = {0};
 +    riff_chunk_t fram_chunk = {0};
 +    const unsigned char *icon_data;
 +
 +    TRACE("bits %p, bits_size %d\n", bits, bits_size);
 +
 +    if (!bits) return 0;
 +
 +    riff_find_chunk( ANI_ACON_ID, ANI_RIFF_ID, &root_chunk, &ACON_chunk );
 +    if (!ACON_chunk.data)
 +    {
 +        ERR("Failed to get root chunk.\n");
 +        return 0;
 +    }
 +
 +    riff_find_chunk( ANI_anih_ID, 0, &ACON_chunk, &anih_chunk );
 +    if (!anih_chunk.data)
 +    {
 +        ERR("Failed to get 'anih' chunk.\n");
 +        return 0;
 +    }
 +    memcpy( &header, anih_chunk.data, sizeof(header) );
 +    dump_ani_header( &header );
 +
 +    riff_find_chunk( ANI_fram_ID, ANI_LIST_ID, &ACON_chunk, &fram_chunk );
 +    if (!fram_chunk.data)
 +    {
 +        ERR("Failed to get icon list.\n");
 +        return 0;
 +    }
 +
 +    /* FIXME: For now, just load the first frame.  Before we can load all the
 +     * frames, we need to write the needed code in wineserver, etc. to handle
 +     * cursors.  Once this code is written, we can extend it to support .ani
 +     * cursors and then update user32 and winex11.drv to load all frames.
 +     *
 +     * Hopefully this will at least make some games (C&C3, etc.) more playable
 +     * in the meantime.
 +     */
 +    FIXME("Loading all frames for .ani cursors not implemented.\n");
 +    icon_data = fram_chunk.data + (2 * sizeof(DWORD));
 +
 +    entry = CURSORICON_FindBestIconFile( (CURSORICONFILEDIR *) icon_data,
 +        width, height, depth );
 +
 +    frame_bits = HeapAlloc( GetProcessHeap(), 0, entry->dwDIBSize );
 +    memcpy( frame_bits, icon_data + entry->dwDIBOffset, entry->dwDIBSize );
 +
 +    if (!header.width || !header.height)
 +    {
 +        header.width = entry->bWidth;
 +        header.height = entry->bHeight;
 +    }
 +
 +    hotspot.x = entry->xHotspot;
 +    hotspot.y = entry->yHotspot;
 +
 +    cursor = CURSORICON_CreateIconFromBMI( (BITMAPINFO *) frame_bits, hotspot,
 +        FALSE, 0x00030000, header.width, header.height, 0 );
 +
 +    HeapFree( GetProcessHeap(), 0, frame_bits );
 +
 +    return cursor;
 +}
 +
 +
 +/**********************************************************************
 + *            CreateIconFromResourceEx (USER32.@)
 + *
 + * FIXME: Convert to mono when cFlag is LR_MONOCHROME. Do something
 + *        with cbSize parameter as well.
 + */
 +HICON WINAPI CreateIconFromResourceEx( PBYTE bits, DWORD cbSize,
 +                                       BOOL bIcon, DWORD dwVersion,
 +                                       int width, int height,
 +                                       UINT cFlag )
 +{
 +    POINT hotspot;
 +    BITMAPINFO *bmi;
 +
 +    TRACE_(cursor)("%p (%u bytes), ver %08x, %ix%i %s %s\n",
 +                   bits, cbSize, dwVersion, width, height,
 +                   bIcon ? "icon" : "cursor", (cFlag & LR_MONOCHROME) ? "mono" : "" );
 +
 +    if (bIcon)
 +    {
 +        hotspot.x = width / 2;
 +        hotspot.y = height / 2;
 +        bmi = (BITMAPINFO *)bits;
 +    }
 +    else /* get the hotspot */
 +    {
 +        SHORT *pt = (SHORT *)bits;
 +        hotspot.x = pt[0];
 +        hotspot.y = pt[1];
 +        bmi = (BITMAPINFO *)(pt + 2);
 +    }
 +
 +    return CURSORICON_CreateIconFromBMI( bmi, hotspot, bIcon, dwVersion,
 +                                       width, height, cFlag );
 +}
 +
 +
 +/**********************************************************************
 + *            CreateIconFromResource (USER32.@)
 + */
 +HICON WINAPI CreateIconFromResource( PBYTE bits, DWORD cbSize,
 +                                           BOOL bIcon, DWORD dwVersion)
 +{
 +    return CreateIconFromResourceEx( bits, cbSize, bIcon, dwVersion, 0,0,0);
 +}
 +
 +
 +static HICON CURSORICON_LoadFromFile( LPCWSTR filename,
 +                             INT width, INT height, INT depth,
 +                             BOOL fCursor, UINT loadflags)
 +{
 +    CURSORICONFILEDIRENTRY *entry;
 +    CURSORICONFILEDIR *dir;
 +    DWORD filesize = 0;
 +    HICON hIcon = 0;
 +    LPBYTE bits;
 +    POINT hotspot;
 +
 +    TRACE("loading %s\n", debugstr_w( filename ));
 +
 +    bits = map_fileW( filename, &filesize );
 +    if (!bits)
 +        return hIcon;
 +
 +    /* Check for .ani. */
 +    if (memcmp( bits, "RIFF", 4 ) == 0)
 +    {
 +        hIcon = CURSORICON_CreateIconFromANI( bits, filesize, width, height,
 +            depth );
 +        goto end;
 +    }
 +
 +    dir = (CURSORICONFILEDIR*) bits;
 +    if ( filesize < sizeof(*dir) )
 +        goto end;
 +
 +    if ( filesize < (sizeof(*dir) + sizeof(dir->idEntries[0])*(dir->idCount-1)) )
 +        goto end;
 +
 +    if ( fCursor )
 +        entry = CURSORICON_FindBestCursorFile( dir, width, height, depth );
 +    else
 +        entry = CURSORICON_FindBestIconFile( dir, width, height, depth );
 +
 +    if ( !entry )
 +        goto end;
 +
 +    /* check that we don't run off the end of the file */
 +    if ( entry->dwDIBOffset > filesize )
 +        goto end;
 +    if ( entry->dwDIBOffset + entry->dwDIBSize > filesize )
 +        goto end;
 +
 +    hotspot.x = entry->xHotspot;
 +    hotspot.y = entry->yHotspot;
 +    hIcon = CURSORICON_CreateIconFromBMI( (BITMAPINFO *)&bits[entry->dwDIBOffset],
 +                                        hotspot, !fCursor, 0x00030000,
 +                                        width, height, loadflags );
 +end:
 +    TRACE("loaded %s -> %p\n", debugstr_w( filename ), hIcon );
 +    UnmapViewOfFile( bits );
 +    return hIcon;
 +}
 +
 +/**********************************************************************
 + *          CURSORICON_Load
 + *
 + * Load a cursor or icon from resource or file.
 + */
 +static HICON CURSORICON_Load(HINSTANCE hInstance, LPCWSTR name,
 +                             INT width, INT height, INT depth,
 +                             BOOL fCursor, UINT loadflags)
 +{
 +    HANDLE handle = 0;
 +    HICON hIcon = 0;
 +    HRSRC hRsrc, hGroupRsrc;
 +    CURSORICONDIR *dir;
 +    CURSORICONDIRENTRY *dirEntry;
 +    LPBYTE bits;
 +    WORD wResId;
 +    DWORD dwBytesInRes;
 +
 +    TRACE("%p, %s, %dx%d, depth %d, fCursor %d, flags 0x%04x\n",
 +          hInstance, debugstr_w(name), width, height, depth, fCursor, loadflags);
 +
 +    if ( loadflags & LR_LOADFROMFILE )    /* Load from file */
 +        return CURSORICON_LoadFromFile( name, width, height, depth, fCursor, loadflags );
 +
 +    if (!hInstance) hInstance = User32Instance;  /* Load OEM cursor/icon */
 +
 +    /* don't cache 16-bit instances (FIXME: should never get 16-bit instances in the first place) */
 +    if ((ULONG_PTR)hInstance >> 16 == 0) loadflags &= ~LR_SHARED;
 +
 +    /* Get directory resource ID */
 +
 +    if (!(hRsrc = FindResourceW( hInstance, name,
 +                                 (LPWSTR)(fCursor ? RT_GROUP_CURSOR : RT_GROUP_ICON) )))
 +        return 0;
 +    hGroupRsrc = hRsrc;
 +
 +    /* Find the best entry in the directory */
 +
 +    if (!(handle = LoadResource( hInstance, hRsrc ))) return 0;
 +    if (!(dir = LockResource( handle ))) return 0;
 +    if (fCursor)
 +        dirEntry = CURSORICON_FindBestCursorRes( dir, width, height, depth );
 +    else
 +        dirEntry = CURSORICON_FindBestIconRes( dir, width, height, depth );
 +    if (!dirEntry) return 0;
 +    wResId = dirEntry->wResId;
 +    dwBytesInRes = dirEntry->dwBytesInRes;
 +    FreeResource( handle );
 +
 +    /* Load the resource */
 +
 +    if (!(hRsrc = FindResourceW(hInstance,MAKEINTRESOURCEW(wResId),
 +                                (LPWSTR)(fCursor ? RT_CURSOR : RT_ICON) ))) return 0;
 +
 +    /* If shared icon, check whether it was already loaded */
 +    if (    (loadflags & LR_SHARED)
 +         && (hIcon = NtUserFindExistingCursorIcon( hInstance, hRsrc, 0, 0 ) ) != 0 )
 +        return hIcon;
 +
 +    if (!(handle = LoadResource( hInstance, hRsrc ))) return 0;
 +    bits = LockResource( handle );
 +    hIcon = CreateIconFromResourceEx( bits, dwBytesInRes,
 +                                      !fCursor, 0x00030000, width, height, loadflags);
 +    FreeResource( handle );
 +
 +    /* If shared icon, add to icon cache */
 +
 +      if (hIcon && 0 != (loadflags & LR_SHARED))
 +      {
 +#if 1
 +         NtUserSetCursorIconData((HICON)hIcon, NULL, NULL, hInstance, hRsrc,
 +                                 (HRSRC)NULL);
 +#else
 +         ICONINFO iconInfo;
 +
 +         if(NtUserGetIconInfo(ResIcon, &iconInfo, NULL, NULL, NULL, FALSE))
 +            NtUserSetCursorIconData((HICON)hIcon, hinst, NULL, &iconInfo);
 +#endif
 +        }
 +
 +    return hIcon;
 +}
 +
 +
 +/*************************************************************************
 + * CURSORICON_ExtCopy
 + *
 + * Copies an Image from the Cache if LR_COPYFROMRESOURCE is specified
 + *
 + * PARAMS
 + *      Handle     [I] handle to an Image
 + *      nType      [I] Type of Handle (IMAGE_CURSOR | IMAGE_ICON)
 + *      iDesiredCX [I] The Desired width of the Image
 + *      iDesiredCY [I] The desired height of the Image
 + *      nFlags     [I] The flags from CopyImage
 + *
 + * RETURNS
 + *     Success: The new handle of the Image
 + *
 + * NOTES
 + *     LR_COPYDELETEORG and LR_MONOCHROME are currently not implemented.
 + *     LR_MONOCHROME should be implemented by CreateIconFromResourceEx.
 + *     LR_COPYFROMRESOURCE will only work if the Image is in the Cache.
 + *
 + *
 + */
 +
 +static HICON CURSORICON_ExtCopy(HICON hIcon, UINT nType,
 +                                INT iDesiredCX, INT iDesiredCY,
 +                                UINT nFlags)
 +{
 +    HICON hNew=0;
 +
 +    TRACE_(icon)("hIcon %p, nType %u, iDesiredCX %i, iDesiredCY %i, nFlags %u\n",
 +                 hIcon, nType, iDesiredCX, iDesiredCY, nFlags);
 +
 +    if(hIcon == 0)
 +    {
 +        return 0;
 +    }
 +
 +    /* Best Fit or Monochrome */
 +    if( (nFlags & LR_COPYFROMRESOURCE
 +        && (iDesiredCX > 0 || iDesiredCY > 0))
 +        || nFlags & LR_MONOCHROME)
 +    {
 +              TRACE("Copying from resource isn't implemented yet\n");
 +              hNew = CopyIcon(hIcon);
 +
 +#if 0
 +        ICONCACHE* pIconCache = CURSORICON_FindCache(hIcon);
 +
 +        /* Not Found in Cache, then do a straight copy
 +        */
 +        if(pIconCache == NULL)
 +        {
 +            hNew = CopyIcon( hIcon );
 +            if(nFlags & LR_COPYFROMRESOURCE)
 +            {
 +                TRACE_(icon)("LR_COPYFROMRESOURCE: Failed to load from cache\n");
 +            }
 +        }
 +        else
 +        {
 +            int iTargetCY = iDesiredCY, iTargetCX = iDesiredCX;
 +            LPBYTE pBits;
 +            HANDLE hMem;
 +            HRSRC hRsrc;
 +            DWORD dwBytesInRes;
 +            WORD wResId;
 +            CURSORICONDIR *pDir;
 +            CURSORICONDIRENTRY *pDirEntry;
 +            BOOL bIsIcon = (nType == IMAGE_ICON);
 +
 +            /* Completing iDesiredCX CY for Monochrome Bitmaps if needed
 +            */
 +            if(((nFlags & LR_MONOCHROME) && !(nFlags & LR_COPYFROMRESOURCE))
 +                || (iDesiredCX == 0 && iDesiredCY == 0))
 +            {
 +                iDesiredCY = GetSystemMetrics(bIsIcon ?
 +                    SM_CYICON : SM_CYCURSOR);
 +                iDesiredCX = GetSystemMetrics(bIsIcon ?
 +                    SM_CXICON : SM_CXCURSOR);
 +            }
 +
 +            /* Retrieve the CURSORICONDIRENTRY
 +            */
 +            if (!(hMem = LoadResource( pIconCache->hModule ,
 +                            pIconCache->hGroupRsrc)))
 +            {
 +                return 0;
 +            }
 +            if (!(pDir = LockResource( hMem )))
 +            {
 +                return 0;
 +            }
 +
 +            /* Find Best Fit
 +            */
 +            if(bIsIcon)
 +            {
 +                pDirEntry = CURSORICON_FindBestIconRes(
 +                                pDir, iDesiredCX, iDesiredCY, 256 );
 +            }
 +            else
 +            {
 +                pDirEntry = CURSORICON_FindBestCursorRes(
 +                                pDir, iDesiredCX, iDesiredCY, 1);
 +            }
 +
 +            wResId = pDirEntry->wResId;
 +            dwBytesInRes = pDirEntry->dwBytesInRes;
 +            FreeResource(hMem);
 +
 +            TRACE_(icon)("ResID %u, BytesInRes %u, Width %d, Height %d DX %d, DY %d\n",
 +                wResId, dwBytesInRes,  pDirEntry->ResInfo.icon.bWidth,
 +                pDirEntry->ResInfo.icon.bHeight, iDesiredCX, iDesiredCY);
 +
 +            /* Get the Best Fit
 +            */
 +            if (!(hRsrc = FindResourceW(pIconCache->hModule ,
 +                MAKEINTRESOURCEW(wResId), (LPWSTR)(bIsIcon ? RT_ICON : RT_CURSOR))))
 +            {
 +                return 0;
 +            }
 +            if (!(hMem = LoadResource( pIconCache->hModule , hRsrc )))
 +            {
 +                return 0;
 +            }
 +
 +            pBits = LockResource( hMem );
 +
 +            if(nFlags & LR_DEFAULTSIZE)
 +            {
 +                iTargetCY = GetSystemMetrics(SM_CYICON);
 +                iTargetCX = GetSystemMetrics(SM_CXICON);
 +            }
 +
 +            /* Create a New Icon with the proper dimension
 +            */
 +            hNew = CreateIconFromResourceEx( pBits, dwBytesInRes,
 +                       bIsIcon, 0x00030000, iTargetCX, iTargetCY, nFlags);
 +            FreeResource(hMem);
 +        }
 +#endif
 +    }
 +    else hNew = CopyIcon( hIcon );
 +    return hNew;
 +}
 +
 +
 +/***********************************************************************
 + *            CreateCursor (USER32.@)
 + */
 +HCURSOR WINAPI CreateCursor( HINSTANCE hInstance,
 +                                 INT xHotSpot, INT yHotSpot,
 +                                 INT nWidth, INT nHeight,
 +                                 LPCVOID lpANDbits, LPCVOID lpXORbits )
 +{
 +    ICONINFO info;
 +    HCURSOR hCursor;
 +
 +    TRACE_(cursor)("%dx%d spot=%d,%d xor=%p and=%p\n",
 +                    nWidth, nHeight, xHotSpot, yHotSpot, lpXORbits, lpANDbits);
 +
 +    info.fIcon = FALSE;
 +    info.xHotspot = xHotSpot;
 +    info.yHotspot = yHotSpot;
 +    info.hbmMask = CreateBitmap( nWidth, nHeight, 1, 1, lpANDbits );
 +    info.hbmColor = CreateBitmap( nWidth, nHeight, 1, 1, lpXORbits );
 +    hCursor = CreateIconIndirect( &info );
 +    DeleteObject( info.hbmMask );
 +    DeleteObject( info.hbmColor );
 +    return hCursor;
 +}
 +
 +
 +/***********************************************************************
 + *            CreateIcon (USER32.@)
 + *
 + *  Creates an icon based on the specified bitmaps. The bitmaps must be
 + *  provided in a device dependent format and will be resized to
 + *  (SM_CXICON,SM_CYICON) and depth converted to match the screen's color
 + *  depth. The provided bitmaps must be top-down bitmaps.
 + *  Although Windows does not support 15bpp(*) this API must support it
 + *  for Winelib applications.
 + *
 + *  (*) Windows does not support 15bpp but it supports the 555 RGB 16bpp
 + *      format!
 + *
 + * RETURNS
 + *  Success: handle to an icon
 + *  Failure: NULL
 + *
 + * FIXME: Do we need to resize the bitmaps?
 + */
 +HICON WINAPI CreateIcon(
 +    HINSTANCE hInstance,  /* [in] the application's hInstance */
 +    int       nWidth,     /* [in] the width of the provided bitmaps */
 +    int       nHeight,    /* [in] the height of the provided bitmaps */
 +    BYTE      bPlanes,    /* [in] the number of planes in the provided bitmaps */
 +    BYTE      bBitsPixel, /* [in] the number of bits per pixel of the lpXORbits bitmap */
 +    const BYTE*   lpANDbits,  /* [in] a monochrome bitmap representing the icon's mask */
 +    const BYTE*   lpXORbits)  /* [in] the icon's 'color' bitmap */
 +{
 +    ICONINFO iinfo;
 +    HICON hIcon;
 +
 +    TRACE_(icon)("%dx%d, planes %d, bpp %d, xor %p, and %p\n",
 +                 nWidth, nHeight, bPlanes, bBitsPixel, lpXORbits, lpANDbits);
 +
 +    iinfo.fIcon = TRUE;
 +    iinfo.xHotspot = nWidth / 2;
 +    iinfo.yHotspot = nHeight / 2;
 +    if (bPlanes * bBitsPixel > 1)
 +    {
 +        iinfo.hbmColor = CreateBitmap( nWidth, nHeight, bPlanes, bBitsPixel, lpXORbits );
 +        iinfo.hbmMask = CreateBitmap( nWidth, nHeight, 1, 1, lpANDbits );
 +    }
 +    else
 +    {
 +        iinfo.hbmMask = CreateBitmap( nWidth, nHeight * 2, 1, 1, lpANDbits );
 +        iinfo.hbmColor = NULL;
 +    }
 +
 +    hIcon = CreateIconIndirect( &iinfo );
 +
 +    DeleteObject( iinfo.hbmMask );
 +    if (iinfo.hbmColor) DeleteObject( iinfo.hbmColor );
 +
 +    return hIcon;
 +}
 +
 +
 +/***********************************************************************
 + *            CopyIcon (USER32.@)
 + */
 +HICON WINAPI CopyIcon( HICON hIcon )
 +{
 +    HICON hRetIcon = NULL;
 +    ICONINFO IconInfo;
 +
 +    if(GetIconInfo(hIcon, &IconInfo))
 +    {
 +        hRetIcon = CreateIconIndirect(&IconInfo);
 +        DeleteObject(IconInfo.hbmColor);
 +        DeleteObject(IconInfo.hbmMask);
 +    }
 +
 +    return hRetIcon;
 +}
 +
 +
 +/***********************************************************************
 + *            DestroyIcon (USER32.@)
 + */
 +BOOL WINAPI DestroyIcon( HICON hIcon )
 +{
 +    TRACE_(icon)("%p\n", hIcon );
 +
 +    return NtUserDestroyCursor(hIcon, 0);
 +}
 +
 +
 +/***********************************************************************
 + *            DestroyCursor (USER32.@)
 + */
 +BOOL WINAPI DestroyCursor( HCURSOR hCursor )
 +{
 +    if (GetCursor() == hCursor)
 +    {
 +        WARN_(cursor)("Destroying active cursor!\n" );
 +        return FALSE;
 +    }
 +    return DestroyIcon( hCursor );
 +}
 +
 +/***********************************************************************
 + *            DrawIcon (USER32.@)
 + */
 +BOOL WINAPI DrawIcon( HDC hdc, INT x, INT y, HICON hIcon )
 +{
 +    return DrawIconEx( hdc, x, y, hIcon, 0, 0, 0, 0, DI_NORMAL | DI_COMPAT | DI_DEFAULTSIZE );
 +}
 +
 +/***********************************************************************
 + *            ShowCursor (USER32.@)
 + */
 +INT WINAPI /*DECLSPEC_HOTPATCH*/ ShowCursor( BOOL bShow )
 +{
 +    return NtUserShowCursor(bShow);
 +}
 +
 +/***********************************************************************
 + *            GetCursor (USER32.@)
 + */
 +HCURSOR WINAPI GetCursor(void)
 +{
 +    CURSORINFO ci;
 +    ci.cbSize = sizeof(CURSORINFO);
 +    if(NtUserGetCursorInfo(&ci))
 +        return ci.hCursor;
 +    else
 +        return (HCURSOR)0;
 +}
 +
 +
 +
 +/***********************************************************************
 + *            SetSystemCursor (USER32.@)
 + */
 +BOOL WINAPI SetSystemCursor(HCURSOR hcur, DWORD id)
 +{
 +    FIXME("(%p,%08x),stub!\n",  hcur, id);
 +    return TRUE;
 +}
 +
 +
 +/**********************************************************************
 + *            LookupIconIdFromDirectoryEx (USER32.@)
 + */
 +INT WINAPI LookupIconIdFromDirectoryEx( LPBYTE xdir, BOOL bIcon,
 +             INT width, INT height, UINT cFlag )
 +{
 +    CURSORICONDIR       *dir = (CURSORICONDIR*)xdir;
 +    UINT retVal = 0;
 +    if( dir && !dir->idReserved && (dir->idType & 3) )
 +    {
 +        CURSORICONDIRENTRY* entry;
 +
 +        const HDC hdc = GetDC(0);
 +        const int depth = (cFlag & LR_MONOCHROME) ?
 +            1 : GetDeviceCaps(hdc, BITSPIXEL);
 +        ReleaseDC(0, hdc);
 +
 +        if( bIcon )
 +            entry = CURSORICON_FindBestIconRes( dir, width, height, depth );
 +        else
 +            entry = CURSORICON_FindBestCursorRes( dir, width, height, depth );
 +
 +        if( entry ) retVal = entry->wResId;
 +    }
 +    else WARN_(cursor)("invalid resource directory\n");
 +    return retVal;
 +}
 +
 +/**********************************************************************
 + *              LookupIconIdFromDirectory (USER32.@)
 + */
 +INT WINAPI LookupIconIdFromDirectory( LPBYTE dir, BOOL bIcon )
 +{
 +    return LookupIconIdFromDirectoryEx( dir, bIcon,
 +           bIcon ? GetSystemMetrics(SM_CXICON) : GetSystemMetrics(SM_CXCURSOR),
 +           bIcon ? GetSystemMetrics(SM_CYICON) : GetSystemMetrics(SM_CYCURSOR), bIcon ? 0 : LR_MONOCHROME );
 +}
 +
 +/***********************************************************************
 + *              LoadCursorW (USER32.@)
 + */
 +HCURSOR WINAPI LoadCursorW(HINSTANCE hInstance, LPCWSTR name)
 +{
 +    TRACE("%p, %s\n", hInstance, debugstr_w(name));
 +
 +    return LoadImageW( hInstance, name, IMAGE_CURSOR, 0, 0,
 +                       LR_SHARED | LR_DEFAULTSIZE );
 +}
 +
 +/***********************************************************************
 + *            LoadCursorA (USER32.@)
 + */
 +HCURSOR WINAPI LoadCursorA(HINSTANCE hInstance, LPCSTR name)
 +{
 +    TRACE("%p, %s\n", hInstance, debugstr_a(name));
 +
 +    return LoadImageA( hInstance, name, IMAGE_CURSOR, 0, 0,
 +                       LR_SHARED | LR_DEFAULTSIZE );
 +}
 +
 +/***********************************************************************
 + *            LoadCursorFromFileW (USER32.@)
 + */
 +HCURSOR WINAPI LoadCursorFromFileW (LPCWSTR name)
 +{
 +    TRACE("%s\n", debugstr_w(name));
 +
 +    return LoadImageW( 0, name, IMAGE_CURSOR, 0, 0,
 +                       LR_LOADFROMFILE | LR_DEFAULTSIZE );
 +}
 +
 +/***********************************************************************
 + *            LoadCursorFromFileA (USER32.@)
 + */
 +HCURSOR WINAPI LoadCursorFromFileA (LPCSTR name)
 +{
 +    TRACE("%s\n", debugstr_a(name));
 +
 +    return LoadImageA( 0, name, IMAGE_CURSOR, 0, 0,
 +                       LR_LOADFROMFILE | LR_DEFAULTSIZE );
 +}
 +
 +/***********************************************************************
 + *            LoadIconW (USER32.@)
 + */
 +HICON WINAPI LoadIconW(HINSTANCE hInstance, LPCWSTR name)
 +{
 +    TRACE("%p, %s\n", hInstance, debugstr_w(name));
 +
 +    return LoadImageW( hInstance, name, IMAGE_ICON, 0, 0,
 +                       LR_SHARED | LR_DEFAULTSIZE );
 +}
 +
 +/***********************************************************************
 + *              LoadIconA (USER32.@)
 + */
 +HICON WINAPI LoadIconA(HINSTANCE hInstance, LPCSTR name)
 +{
 +    TRACE("%p, %s\n", hInstance, debugstr_a(name));
 +
 +    return LoadImageA( hInstance, name, IMAGE_ICON, 0, 0,
 +                       LR_SHARED | LR_DEFAULTSIZE );
 +}
 +
 +/**********************************************************************
 + *              GetIconInfo (USER32.@)
 + */
 +BOOL WINAPI GetIconInfo(HICON hIcon, PICONINFO iconinfo)
 +{
 +    return NtUserGetIconInfo(hIcon, iconinfo, 0, 0, 0, 0);
 +}
 +
 +/* copy an icon bitmap, even when it can't be selected into a DC */
 +/* helper for CreateIconIndirect */
 +static void stretch_blt_icon( HDC hdc_dst, int dst_x, int dst_y, int dst_width, int dst_height,
 +                              HBITMAP src, int width, int height )
 +{
 +    HDC hdc = CreateCompatibleDC( 0 );
 +
 +    if (!SelectObject( hdc, src ))  /* do it the hard way */
 +    {
 +        BITMAPINFO *info;
 +        void *bits;
 +
 +        if (!(info = HeapAlloc( GetProcessHeap(), 0, FIELD_OFFSET( BITMAPINFO, bmiColors[256] )))) return;
 +        info->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
 +        info->bmiHeader.biWidth = width;
 +        info->bmiHeader.biHeight = height;
 +        info->bmiHeader.biPlanes = GetDeviceCaps( hdc_dst, PLANES );
 +        info->bmiHeader.biBitCount = GetDeviceCaps( hdc_dst, BITSPIXEL );
 +        info->bmiHeader.biCompression = BI_RGB;
 +        info->bmiHeader.biSizeImage = height * get_dib_width_bytes( width, info->bmiHeader.biBitCount );
 +        info->bmiHeader.biXPelsPerMeter = 0;
 +        info->bmiHeader.biYPelsPerMeter = 0;
 +        info->bmiHeader.biClrUsed = 0;
 +        info->bmiHeader.biClrImportant = 0;
 +        bits = HeapAlloc( GetProcessHeap(), 0, info->bmiHeader.biSizeImage );
 +        if (bits && GetDIBits( hdc, src, 0, height, bits, info, DIB_RGB_COLORS ))
 +            StretchDIBits( hdc_dst, dst_x, dst_y, dst_width, dst_height,
 +                           0, 0, width, height, bits, info, DIB_RGB_COLORS, SRCCOPY );
 +
 +        HeapFree( GetProcessHeap(), 0, bits );
 +        HeapFree( GetProcessHeap(), 0, info );
 +    }
 +    else StretchBlt( hdc_dst, dst_x, dst_y, dst_width, dst_height, hdc, 0, 0, width, height, SRCCOPY );
 +
 +    DeleteDC( hdc );
 +}
 +
 +/**********************************************************************
 + *            CreateIconIndirect (USER32.@)
 + */
 +HICON WINAPI CreateIconIndirect(PICONINFO iconinfo)
 +{
 +    BITMAP bmpXor, bmpAnd;
 +    HBITMAP color = 0, mask;
 +    int width, height;
 +    HDC hdc;
 +      ICONINFO iinfo;
 +
 +    TRACE("color %p, mask %p, hotspot %ux%u, fIcon %d\n",
 +           iconinfo->hbmColor, iconinfo->hbmMask,
 +           iconinfo->xHotspot, iconinfo->yHotspot, iconinfo->fIcon);
 +
 +    if (!iconinfo->hbmMask) return 0;
 +
 +    GetObjectW( iconinfo->hbmMask, sizeof(bmpAnd), &bmpAnd );
 +    TRACE("mask: width %d, height %d, width bytes %d, planes %u, bpp %u\n",
 +           bmpAnd.bmWidth, bmpAnd.bmHeight, bmpAnd.bmWidthBytes,
 +           bmpAnd.bmPlanes, bmpAnd.bmBitsPixel);
 +
 +    if (iconinfo->hbmColor)
 +    {
 +        GetObjectW( iconinfo->hbmColor, sizeof(bmpXor), &bmpXor );
 +        TRACE("color: width %d, height %d, width bytes %d, planes %u, bpp %u\n",
 +               bmpXor.bmWidth, bmpXor.bmHeight, bmpXor.bmWidthBytes,
 +               bmpXor.bmPlanes, bmpXor.bmBitsPixel);
 +
 +        // the size of the mask bitmap always determines the icon size!
 +        width = bmpAnd.bmWidth;
 +        height = bmpAnd.bmHeight;
 +        if (bmpXor.bmPlanes * bmpXor.bmBitsPixel != 1)
 +        {
 +            color = CreateBitmap( width, height, bmpXor.bmPlanes, bmpXor.bmBitsPixel, NULL );
 +                      if(!color)
 +                      {
 +                              ERR("Unable to create color bitmap!\n");
 +                              return NULL;
 +                      }
 +            mask = CreateBitmap( width, height, 1, 1, NULL );
 +                      if(!mask)
 +                      {
 +                              ERR("Unable to create mask bitmap!\n");
 +                              DeleteObject(color);
 +                              return NULL;
 +                      }
 +        }
 +        else
 +              {
 +                      mask = CreateBitmap( width, height * 2, 1, 1, NULL );
 +                      if(!mask)
 +                      {
 +                              ERR("Unable to create mask bitmap!\n");
 +                              return NULL;
 +                      }
 +              }
 +    }
 +    else
 +    {
 +        width = bmpAnd.bmWidth;
 +        height = bmpAnd.bmHeight;
 +        mask = CreateBitmap( width, height, 1, 1, NULL );
 +    }
 +
 +    hdc = CreateCompatibleDC( 0 );
 +    SelectObject( hdc, mask );
 +    stretch_blt_icon( hdc, 0, 0, width, height, iconinfo->hbmMask, bmpAnd.bmWidth, bmpAnd.bmHeight );
 +
 +    if (color)
 +    {
 +        SelectObject( hdc, color );
 +        stretch_blt_icon( hdc, 0, 0, width, height, iconinfo->hbmColor, width, height );
 +    }
 +    else if (iconinfo->hbmColor)
 +    {
 +        stretch_blt_icon( hdc, 0, height, width, height, iconinfo->hbmColor, width, height );
 +    }
 +    else height /= 2;
 +
 +    DeleteDC( hdc );
 +
 +    iinfo.hbmColor = color ;
 +    iinfo.hbmMask = mask ;
 +    iinfo.fIcon = iconinfo->fIcon;
 +    if (iinfo.fIcon)
 +    {
 +        iinfo.xHotspot = width / 2;
 +        iinfo.yHotspot = height / 2;
 +    }
 +    else
 +    {
 +        iinfo.xHotspot = iconinfo->xHotspot;
 +        iinfo.yHotspot = iconinfo->yHotspot;
 +    }
 +
 +      return CreateCursorIconHandle(&iinfo);
 +}
 +
 +/******************************************************************************
 + *            DrawIconEx (USER32.@) Draws an icon or cursor on device context
 + *
 + * NOTES
 + *    Why is this using SM_CXICON instead of SM_CXCURSOR?
 + *
 + * PARAMS
 + *    hdc     [I] Handle to device context
 + *    x0      [I] X coordinate of upper left corner
 + *    y0      [I] Y coordinate of upper left corner
 + *    hIcon   [I] Handle to icon to draw
 + *    cxWidth [I] Width of icon
 + *    cyWidth [I] Height of icon
 + *    istep   [I] Index of frame in animated cursor
 + *    hbr     [I] Handle to background brush
 + *    flags   [I] Icon-drawing flags
 + *
 + * RETURNS
 + *    Success: TRUE
 + *    Failure: FALSE
 + */
 +BOOL WINAPI DrawIconEx( HDC hdc, INT xLeft, INT yTop, HICON hIcon,
 +                            INT cxWidth, INT cyWidth, UINT istepIfAniCur,
 +                            HBRUSH hbrFlickerFreeDraw, UINT diFlags )
 +{
 +    return NtUserDrawIconEx(hdc, xLeft, yTop, hIcon, cxWidth, cyWidth,
 +                            istepIfAniCur, hbrFlickerFreeDraw, diFlags,
 +                            0, 0);
 +}
 +
 +/***********************************************************************
 + *           DIB_FixColorsToLoadflags
 + *
 + * Change color table entries when LR_LOADTRANSPARENT or LR_LOADMAP3DCOLORS
 + * are in loadflags
 + */
 +static void DIB_FixColorsToLoadflags(BITMAPINFO * bmi, UINT loadflags, BYTE pix)
 +{
 +    int colors;
 +    COLORREF c_W, c_S, c_F, c_L, c_C;
 +    int incr,i;
 +    RGBQUAD *ptr;
 +    int bitmap_type;
 +    LONG width;
 +    LONG height;
 +    WORD bpp;
 +    DWORD compr;
 +
 +    if (((bitmap_type = DIB_GetBitmapInfo((BITMAPINFOHEADER*) bmi, &width, &height, &bpp, &compr)) == -1))
 +    {
 +        WARN_(resource)("Invalid bitmap\n");
 +        return;
 +    }
 +
 +    if (bpp > 8) return;
 +
 +    if (bitmap_type == 0) /* BITMAPCOREHEADER */
 +    {
 +        incr = 3;
 +        colors = 1 << bpp;
 +    }
 +    else
 +    {
 +        incr = 4;
 +        colors = bmi->bmiHeader.biClrUsed;
 +        if (colors > 256) colors = 256;
 +        if (!colors && (bpp <= 8)) colors = 1 << bpp;
 +    }
 +
 +    c_W = GetSysColor(COLOR_WINDOW);
 +    c_S = GetSysColor(COLOR_3DSHADOW);
 +    c_F = GetSysColor(COLOR_3DFACE);
 +    c_L = GetSysColor(COLOR_3DLIGHT);
 +
 +    if (loadflags & LR_LOADTRANSPARENT) {
 +        switch (bpp) {
 +        case 1: pix = pix >> 7; break;
 +        case 4: pix = pix >> 4; break;
 +        case 8: break;
 +        default:
 +            WARN_(resource)("(%d): Unsupported depth\n", bpp);
 +            return;
 +        }
 +        if (pix >= colors) {
 +            WARN_(resource)("pixel has color index greater than biClrUsed!\n");
 +            return;
 +        }
 +        if (loadflags & LR_LOADMAP3DCOLORS) c_W = c_F;
 +        ptr = (RGBQUAD*)((char*)bmi->bmiColors+pix*incr);
 +        ptr->rgbBlue = GetBValue(c_W);
 +        ptr->rgbGreen = GetGValue(c_W);
 +        ptr->rgbRed = GetRValue(c_W);
 +    }
 +    if (loadflags & LR_LOADMAP3DCOLORS)
 +        for (i=0; i<colors; i++) {
 +            ptr = (RGBQUAD*)((char*)bmi->bmiColors+i*incr);
 +            c_C = RGB(ptr->rgbRed, ptr->rgbGreen, ptr->rgbBlue);
 +            if (c_C == RGB(128, 128, 128)) {
 +                ptr->rgbRed = GetRValue(c_S);
 +                ptr->rgbGreen = GetGValue(c_S);
 +                ptr->rgbBlue = GetBValue(c_S);
 +            } else if (c_C == RGB(192, 192, 192)) {
 +                ptr->rgbRed = GetRValue(c_F);
 +                ptr->rgbGreen = GetGValue(c_F);
 +                ptr->rgbBlue = GetBValue(c_F);
 +            } else if (c_C == RGB(223, 223, 223)) {
 +                ptr->rgbRed = GetRValue(c_L);
 +                ptr->rgbGreen = GetGValue(c_L);
 +                ptr->rgbBlue = GetBValue(c_L);
 +            }
 +        }
 +}
 +
 +
 +/**********************************************************************
 + *       BITMAP_Load
 + */
 +static HBITMAP BITMAP_Load( HINSTANCE instance, LPCWSTR name,
 +                            INT desiredx, INT desiredy, UINT loadflags )
 +{
 +    HBITMAP hbitmap = 0, orig_bm;
 +    HRSRC hRsrc;
 +    HGLOBAL handle;
 +    char *ptr = NULL;
 +    BITMAPINFO *info, *fix_info = NULL, *scaled_info = NULL;
 +    int size;
 +    BYTE pix;
 +    char *bits;
 +    LONG width, height, new_width, new_height;
 +    WORD bpp_dummy;
 +    DWORD compr_dummy, offbits = 0;
 +    INT bm_type;
 +    HDC screen_mem_dc = NULL;
 +
 +    if (!(loadflags & LR_LOADFROMFILE))
 +    {
 +        if (!instance)
 +        {
 +            /* OEM bitmap: try to load the resource from user32.dll */
 +            instance = User32Instance;
 +        }
 +
 +        if (!(hRsrc = FindResourceW( instance, name, (LPWSTR)RT_BITMAP ))) return 0;
 +        if (!(handle = LoadResource( instance, hRsrc ))) return 0;
 +
 +        if ((info = LockResource( handle )) == NULL) return 0;
 +    }
 +    else
 +    {
 +        BITMAPFILEHEADER * bmfh;
 +
 +        if (!(ptr = map_fileW( name, NULL ))) return 0;
 +        info = (BITMAPINFO *)(ptr + sizeof(BITMAPFILEHEADER));
 +        bmfh = (BITMAPFILEHEADER *)ptr;
 +        if (bmfh->bfType != 0x4d42 /* 'BM' */)
 +        {
 +            WARN("Invalid/unsupported bitmap format!\n");
 +            goto end_close;
 +        }
 +        if (bmfh->bfOffBits) offbits = bmfh->bfOffBits - sizeof(BITMAPFILEHEADER);
 +    }
 +
 +    size = bitmap_info_size(info, DIB_RGB_COLORS);
 +    fix_info = HeapAlloc(GetProcessHeap(), 0, size);
 +    scaled_info = HeapAlloc(GetProcessHeap(), 0, size);
 +
 +    if (!fix_info || !scaled_info) goto end;
 +    memcpy(fix_info, info, size);
 +
 +    pix = *((LPBYTE)info + size);
 +    DIB_FixColorsToLoadflags(fix_info, loadflags, pix);
 +
 +    memcpy(scaled_info, fix_info, size);
 +    bm_type = DIB_GetBitmapInfo( &fix_info->bmiHeader, &width, &height,
 +                                 &bpp_dummy, &compr_dummy);
 +    if(desiredx != 0)
 +        new_width = desiredx;
 +    else
 +        new_width = width;
 +
 +    if(desiredy != 0)
 +        new_height = height > 0 ? desiredy : -desiredy;
 +    else
 +        new_height = height;
 +
 +    if(bm_type == 0)
 +    {
 +        BITMAPCOREHEADER *core = (BITMAPCOREHEADER *)&scaled_info->bmiHeader;
 +        core->bcWidth = new_width;
 +        core->bcHeight = new_height;
 +    }
 +    else
 +    {
 +        /* Some sanity checks for BITMAPINFO (not applicable to BITMAPCOREINFO) */
 +        if (info->bmiHeader.biHeight > 65535 || info->bmiHeader.biWidth > 65535) {
 +            WARN("Broken BitmapInfoHeader!\n");
 +            goto end;
 +        }
 +
 +        scaled_info->bmiHeader.biWidth = new_width;
 +        scaled_info->bmiHeader.biHeight = new_height;
 +    }
 +
 +    if (new_height < 0) new_height = -new_height;
 +
 +    if (!screen_dc) screen_dc = CreateDCW( DISPLAYW, NULL, NULL, NULL );
 +    if (!(screen_mem_dc = CreateCompatibleDC( screen_dc ))) goto end;
 +
 +    bits = (char *)info + (offbits ? offbits : size);
 +
 +    if (loadflags & LR_CREATEDIBSECTION)
 +    {
 +        scaled_info->bmiHeader.biCompression = 0; /* DIBSection can't be compressed */
 +        hbitmap = CreateDIBSection(screen_dc, scaled_info, DIB_RGB_COLORS, NULL, 0, 0);
 +    }
 +    else
 +    {
 +        if (is_dib_monochrome(fix_info))
 +            hbitmap = CreateBitmap(new_width, new_height, 1, 1, NULL);
 +        else
 +            hbitmap = CreateCompatibleBitmap(screen_dc, new_width, new_height);
 +    }
 +
 +    orig_bm = SelectObject(screen_mem_dc, hbitmap);
 +    StretchDIBits(screen_mem_dc, 0, 0, new_width, new_height, 0, 0, width, height, bits, fix_info, DIB_RGB_COLORS, SRCCOPY);
 +    SelectObject(screen_mem_dc, orig_bm);
 +
 +end:
 +    if (screen_mem_dc) DeleteDC(screen_mem_dc);
 +    HeapFree(GetProcessHeap(), 0, scaled_info);
 +    HeapFree(GetProcessHeap(), 0, fix_info);
 +end_close:
 +    if (loadflags & LR_LOADFROMFILE) UnmapViewOfFile( ptr );
 +
 +    return hbitmap;
 +}
 +
 +/**********************************************************************
 + *            LoadImageA (USER32.@)
 + *
 + * See LoadImageW.
 + */
 +HANDLE WINAPI LoadImageA( HINSTANCE hinst, LPCSTR name, UINT type,
 +                              INT desiredx, INT desiredy, UINT loadflags)
 +{
 +    HANDLE res;
 +    LPWSTR u_name;
 +
 +    if (IS_INTRESOURCE(name))
 +        return LoadImageW(hinst, (LPCWSTR)name, type, desiredx, desiredy, loadflags);
 +
 +    __TRY {
 +        DWORD len = MultiByteToWideChar( CP_ACP, 0, name, -1, NULL, 0 );
 +        u_name = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
 +        MultiByteToWideChar( CP_ACP, 0, name, -1, u_name, len );
 +    }
 +    __EXCEPT_PAGE_FAULT {
 +        SetLastError( ERROR_INVALID_PARAMETER );
 +        return 0;
 +    }
 +    __ENDTRY
 +    res = LoadImageW(hinst, u_name, type, desiredx, desiredy, loadflags);
 +    HeapFree(GetProcessHeap(), 0, u_name);
 +    return res;
 +}
 +
 +
 +/******************************************************************************
 + *            LoadImageW (USER32.@) Loads an icon, cursor, or bitmap
 + *
 + * PARAMS
 + *    hinst     [I] Handle of instance that contains image
 + *    name      [I] Name of image
 + *    type      [I] Type of image
 + *    desiredx  [I] Desired width
 + *    desiredy  [I] Desired height
 + *    loadflags [I] Load flags
 + *
 + * RETURNS
 + *    Success: Handle to newly loaded image
 + *    Failure: NULL
 + *
 + * FIXME: Implementation lacks some features, see LR_ defines in winuser.h
 + */
 +HANDLE WINAPI LoadImageW( HINSTANCE hinst, LPCWSTR name, UINT type,
 +                INT desiredx, INT desiredy, UINT loadflags )
 +{
 +    TRACE_(resource)("(%p,%s,%d,%d,%d,0x%08x)\n",
 +                     hinst,debugstr_w(name),type,desiredx,desiredy,loadflags);
 +
 +    if (loadflags & LR_DEFAULTSIZE) {
 +        if (type == IMAGE_ICON) {
 +            if (!desiredx) desiredx = GetSystemMetrics(SM_CXICON);
 +            if (!desiredy) desiredy = GetSystemMetrics(SM_CYICON);
 +        } else if (type == IMAGE_CURSOR) {
 +            if (!desiredx) desiredx = GetSystemMetrics(SM_CXCURSOR);
 +            if (!desiredy) desiredy = GetSystemMetrics(SM_CYCURSOR);
 +        }
 +    }
 +    if (loadflags & LR_LOADFROMFILE) loadflags &= ~LR_SHARED;
 +    switch (type) {
 +    case IMAGE_BITMAP:
 +        return BITMAP_Load( hinst, name, desiredx, desiredy, loadflags );
 +
 +    case IMAGE_ICON:
 +        if (!screen_dc) screen_dc = CreateDCW( DISPLAYW, NULL, NULL, NULL );
 +        if (screen_dc)
 +        {
 +            return CURSORICON_Load(hinst, name, desiredx, desiredy,
 +                                   GetDeviceCaps(screen_dc, BITSPIXEL),
 +                                   FALSE, loadflags);
 +        }
 +        break;
 +
 +    case IMAGE_CURSOR:
 +        return CURSORICON_Load(hinst, name, desiredx, desiredy,
 +                               1, TRUE, loadflags);
 +    }
 +    return 0;
 +}
 +
 +/******************************************************************************
 + *            CopyImage (USER32.@) Creates new image and copies attributes to it
 + *
 + * PARAMS
 + *    hnd      [I] Handle to image to copy
 + *    type     [I] Type of image to copy
 + *    desiredx [I] Desired width of new image
 + *    desiredy [I] Desired height of new image
 + *    flags    [I] Copy flags
 + *
 + * RETURNS
 + *    Success: Handle to newly created image
 + *    Failure: NULL
 + *
 + * BUGS
 + *    Only Windows NT 4.0 supports the LR_COPYRETURNORG flag for bitmaps,
 + *    all other versions (95/2000/XP have been tested) ignore it.
 + *
 + * NOTES
 + *    If LR_CREATEDIBSECTION is absent, the copy will be monochrome for
 + *    a monochrome source bitmap or if LR_MONOCHROME is present, otherwise
 + *    the copy will have the same depth as the screen.
 + *    The content of the image will only be copied if the bit depth of the
 + *    original image is compatible with the bit depth of the screen, or
 + *    if the source is a DIB section.
 + *    The LR_MONOCHROME flag is ignored if LR_CREATEDIBSECTION is present.
 + */
 +HANDLE WINAPI CopyImage( HANDLE hnd, UINT type, INT desiredx,
 +                             INT desiredy, UINT flags )
 +{
 +    TRACE("hnd=%p, type=%u, desiredx=%d, desiredy=%d, flags=%x\n",
 +          hnd, type, desiredx, desiredy, flags);
 +
 +    switch (type)
 +    {
 +        case IMAGE_BITMAP:
 +        {
 +            HBITMAP res = NULL;
 +            DIBSECTION ds;
 +            int objSize;
 +            BITMAPINFO * bi;
 +
 +            objSize = GetObjectW( hnd, sizeof(ds), &ds );
 +            if (!objSize) return 0;
 +            if ((desiredx < 0) || (desiredy < 0)) return 0;
 +
 +            if (flags & LR_COPYFROMRESOURCE)
 +            {
 +                FIXME("The flag LR_COPYFROMRESOURCE is not implemented for bitmaps\n");
 +            }
 +
 +            if (desiredx == 0) desiredx = ds.dsBm.bmWidth;
 +            if (desiredy == 0) desiredy = ds.dsBm.bmHeight;
 +
 +            /* Allocate memory for a BITMAPINFOHEADER structure and a
 +               color table. The maximum number of colors in a color table
 +               is 256 which corresponds to a bitmap with depth 8.
 +               Bitmaps with higher depths don't have color tables. */
 +            bi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BITMAPINFOHEADER) + 256 * sizeof(RGBQUAD));
 +            if (!bi) return 0;
 +
 +            bi->bmiHeader.biSize        = sizeof(bi->bmiHeader);
 +            bi->bmiHeader.biPlanes      = ds.dsBm.bmPlanes;
 +            bi->bmiHeader.biBitCount    = ds.dsBm.bmBitsPixel;
 +            bi->bmiHeader.biCompression = BI_RGB;
 +
 +            if (flags & LR_CREATEDIBSECTION)
 +            {
 +                /* Create a DIB section. LR_MONOCHROME is ignored */
 +                void * bits;
 +                HDC dc = CreateCompatibleDC(NULL);
 +
 +                if (objSize == sizeof(DIBSECTION))
 +                {
 +                    /* The source bitmap is a DIB.
 +                       Get its attributes to create an exact copy */
 +                    memcpy(bi, &ds.dsBmih, sizeof(BITMAPINFOHEADER));
 +                }
 +
 +                /* Get the color table or the color masks */
 +                GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
 +
 +                bi->bmiHeader.biWidth  = desiredx;
 +                bi->bmiHeader.biHeight = desiredy;
 +                bi->bmiHeader.biSizeImage = 0;
 +
 +                res = CreateDIBSection(dc, bi, DIB_RGB_COLORS, &bits, NULL, 0);
 +                DeleteDC(dc);
 +            }
 +            else
 +            {
 +                /* Create a device-dependent bitmap */
 +
 +                BOOL monochrome = (flags & LR_MONOCHROME);
 +
 +                if (objSize == sizeof(DIBSECTION))
 +                {
 +                    /* The source bitmap is a DIB section.
 +                       Get its attributes */
 +                    HDC dc = CreateCompatibleDC(NULL);
 +                    bi->bmiHeader.biSize = sizeof(bi->bmiHeader);
 +                    bi->bmiHeader.biBitCount = ds.dsBm.bmBitsPixel;
 +                    GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
 +                    DeleteDC(dc);
 +
 +                    if (!monochrome && ds.dsBm.bmBitsPixel == 1)
 +                    {
 +                        /* Look if the colors of the DIB are black and white */
 +
 +                        monochrome =
 +                              (bi->bmiColors[0].rgbRed == 0xff
 +                            && bi->bmiColors[0].rgbGreen == 0xff
 +                            && bi->bmiColors[0].rgbBlue == 0xff
 +                            && bi->bmiColors[0].rgbReserved == 0
 +                            && bi->bmiColors[1].rgbRed == 0
 +                            && bi->bmiColors[1].rgbGreen == 0
 +                            && bi->bmiColors[1].rgbBlue == 0
 +                            && bi->bmiColors[1].rgbReserved == 0)
 +                            ||
 +                              (bi->bmiColors[0].rgbRed == 0
 +                            && bi->bmiColors[0].rgbGreen == 0
 +                            && bi->bmiColors[0].rgbBlue == 0
 +                            && bi->bmiColors[0].rgbReserved == 0
 +                            && bi->bmiColors[1].rgbRed == 0xff
 +                            && bi->bmiColors[1].rgbGreen == 0xff
 +                            && bi->bmiColors[1].rgbBlue == 0xff
 +                            && bi->bmiColors[1].rgbReserved == 0);
 +                    }
 +                }
 +                else if (!monochrome)
 +                {
 +                    monochrome = ds.dsBm.bmBitsPixel == 1;
 +                }
 +
 +                if (monochrome)
 +                {
 +                    res = CreateBitmap(desiredx, desiredy, 1, 1, NULL);
 +                }
 +                else
 +                {
 +                    HDC screenDC = GetDC(NULL);
 +                    res = CreateCompatibleBitmap(screenDC, desiredx, desiredy);
 +                    ReleaseDC(NULL, screenDC);
 +                }
 +            }
 +
 +            if (res)
 +            {
 +                /* Only copy the bitmap if it's a DIB section or if it's
 +                   compatible to the screen */
 +                BOOL copyContents;
 +
 +                if (objSize == sizeof(DIBSECTION))
 +                {
 +                    copyContents = TRUE;
 +                }
 +                else
 +                {
 +                    HDC screenDC = GetDC(NULL);
 +                    int screen_depth = GetDeviceCaps(screenDC, BITSPIXEL);
 +                    ReleaseDC(NULL, screenDC);
 +
 +                    copyContents = (ds.dsBm.bmBitsPixel == 1 || ds.dsBm.bmBitsPixel == screen_depth);
 +                }
 +
 +                if (copyContents)
 +                {
 +                    /* The source bitmap may already be selected in a device context,
 +                       use GetDIBits/StretchDIBits and not StretchBlt  */
 +
 +                    HDC dc;
 +                    void * bits;
 +
 +                    dc = CreateCompatibleDC(NULL);
 +
 +                    bi->bmiHeader.biWidth = ds.dsBm.bmWidth;
 +                    bi->bmiHeader.biHeight = ds.dsBm.bmHeight;
 +                    bi->bmiHeader.biSizeImage = 0;
 +                    bi->bmiHeader.biClrUsed = 0;
 +                    bi->bmiHeader.biClrImportant = 0;
 +
 +                    /* Fill in biSizeImage */
 +                    GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, NULL, bi, DIB_RGB_COLORS);
 +                    bits = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, bi->bmiHeader.biSizeImage);
 +
 +                    if (bits)
 +                    {
 +                        HBITMAP oldBmp;
 +
 +                        /* Get the image bits of the source bitmap */
 +                        GetDIBits(dc, hnd, 0, ds.dsBm.bmHeight, bits, bi, DIB_RGB_COLORS);
 +
 +                        /* Copy it to the destination bitmap */
 +                        oldBmp = SelectObject(dc, res);
 +                        StretchDIBits(dc, 0, 0, desiredx, desiredy,
 +                                      0, 0, ds.dsBm.bmWidth, ds.dsBm.bmHeight,
 +                                      bits, bi, DIB_RGB_COLORS, SRCCOPY);
 +                        SelectObject(dc, oldBmp);
 +
 +                        HeapFree(GetProcessHeap(), 0, bits);
 +                    }
 +
 +                    DeleteDC(dc);
 +                }
 +
 +                if (flags & LR_COPYDELETEORG)
 +                {
 +                    DeleteObject(hnd);
 +                }
 +            }
 +            HeapFree(GetProcessHeap(), 0, bi);
 +            return res;
 +        }
 +        case IMAGE_ICON:
 +                return CURSORICON_ExtCopy(hnd,type, desiredx, desiredy, flags);
 +        case IMAGE_CURSOR:
 +                /* Should call CURSORICON_ExtCopy but more testing
 +                 * needs to be done before we change this
 +                 */
 +                if (flags) FIXME("Flags are ignored\n");
 +                return CopyCursor(hnd);
 +    }
 +    return 0;
 +}
 +
 +
 +/******************************************************************************
 + *            LoadBitmapW (USER32.@) Loads bitmap from the executable file
 + *
 + * RETURNS
 + *    Success: Handle to specified bitmap
 + *    Failure: NULL
 + */
 +HBITMAP WINAPI LoadBitmapW(
 +    HINSTANCE instance, /* [in] Handle to application instance */
 +    LPCWSTR name)         /* [in] Address of bitmap resource name */
 +{
 +    return LoadImageW( instance, name, IMAGE_BITMAP, 0, 0, 0 );
 +}
 +
 +/**********************************************************************
 + *            LoadBitmapA (USER32.@)
 + *
 + * See LoadBitmapW.
 + */
 +HBITMAP WINAPI LoadBitmapA( HINSTANCE instance, LPCSTR name )
 +{
 +    return LoadImageA( instance, name, IMAGE_BITMAP, 0, 0, 0 );
 +}
 +
 +HCURSOR
 +CursorIconToCursor(HICON hIcon,
 +                   BOOL SemiTransparent)
 +{
 +    UNIMPLEMENTED;
 +    return 0;
 +}
 +
 +/*
 + * @implemented
 + */
 +BOOL
 +WINAPI
 +SetCursorPos(int X,
 +             int Y)
 +{
 +    return NtUserSetCursorPos(X,Y);
 +}
 +
 +/*
 + * @implemented
 + */
 +BOOL
 +WINAPI
 +GetCursorPos(LPPOINT lpPoint)
 +{
 +    BOOL res;
 +    /* Windows doesn't check if lpPoint == NULL, we do */
 +    if(!lpPoint)
 +    {
 +        SetLastError(ERROR_INVALID_PARAMETER);
 +        return FALSE;
 +    }
 +
 +    res = NtUserGetCursorPos(lpPoint);
 +
 +    return res;
 +}
 +
 +/* INTERNAL ******************************************************************/
 +
 +/* This callback routine is called directly after switching to gui mode */
 +NTSTATUS
 +WINAPI
 +User32SetupDefaultCursors(PVOID Arguments,
 +                          ULONG ArgumentLength)
 +{
 +    BOOL *DefaultCursor = (BOOL*)Arguments;
 +    LRESULT Result = TRUE;
 +
 +    if(*DefaultCursor)
 +    {
 +        /* set default cursor */
 +        SetCursor(LoadCursorW(0, (LPCWSTR)IDC_ARROW));
 +    }
 +    else
 +    {
 +        /* FIXME load system cursor scheme */
 +        SetCursor(0);
 +        SetCursor(LoadCursorW(0, (LPCWSTR)IDC_ARROW));
 +    }
 +
 +    return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS));
 +}
 +
 +BOOL get_icon_size(HICON hIcon, SIZE *size)
 +{
 +    ICONINFO info;
 +    BITMAP bitmap;
 +
 +    if (!GetIconInfo(hIcon, &info)) return FALSE;
 +    if (!GetObject(info.hbmMask, sizeof(bitmap), &bitmap)) return FALSE;
 +
 +    size->cx = bitmap.bmWidth;
 +    size->cy = bitmap.bmHeight;
 +
 +    /* Black and white icons store both the XOR and AND bitmap in hbmMask */
 +    if (!info.hbmColor)
 +    {
 +        size->cy /= 2;
 +    }
 +
 +    return TRUE;
 +}
Simple merge
Simple merge
index 405e780,0000000..3408d73
mode 100644,000000..100644
--- /dev/null
@@@ -1,5266 -1,0 +1,5279 @@@
-     SetCapture(mt.OwnerWnd);
-     (void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, mt.OwnerWnd);
 +/*
 + * COPYRIGHT:       See COPYING in the top level directory
 + * PROJECT:         ReactOS user32.dll
 + * FILE:            user32/windows/menu.c
 + * PURPOSE:         Menus
 + *
 + * PROGRAMMERS:     Casper S. Hornstrup
 + *                  James Tabor
 + */
 +
 +/* INCLUDES ******************************************************************/
 +
 +#include <user32.h>
 +#include <wine/debug.h>
 +
 +LRESULT DefWndNCPaint(HWND hWnd, HRGN hRgn, BOOL Active);
 +
 +WINE_DEFAULT_DEBUG_CHANNEL(menu);
 +
 +/* internal popup menu window messages */
 +
 +#define MM_SETMENUHANDLE      (WM_USER + 0)
 +#define MM_GETMENUHANDLE      (WM_USER + 1)
 +
 +/* internal flags for menu tracking */
 +
 +#define TF_ENDMENU              0x10000
 +#define TF_SUSPENDPOPUP         0x20000
 +#define TF_SKIPREMOVE           0x40000
 +
 +#define ITEM_PREV             -1
 +#define ITEM_NEXT              1
 +
 +/* Internal MenuTrackMenu() flags */
 +#define TPM_INTERNAL          0xF0000000
 +#define TPM_BUTTONDOWN                0x40000000              /* menu was clicked before tracking */
 +#define TPM_POPUPMENU           0x20000000              /* menu is a popup menu */
 +
 +
 +#define MENU_TYPE_MASK (MF_STRING | MF_BITMAP | MF_OWNERDRAW | MF_SEPARATOR)
 +
 +#define MENU_ITEM_TYPE(flags) ((flags) & MENU_TYPE_MASK)
 +
 +/* macro to test that flags do not indicate bitmap, ownerdraw or separator */
 +#define IS_STRING_ITEM(flags) (MF_STRING == MENU_ITEM_TYPE(flags))
 +#define IS_MAGIC_BITMAP(id) ((id) && ((INT_PTR)(id) < 12) && ((INT_PTR)(id) >= -1))
 +
 +#define IS_SYSTEM_MENU(MenuInfo)  \
 +      (0 == ((MenuInfo)->Flags & MF_POPUP) && 0 != ((MenuInfo)->Flags & MF_SYSMENU))
 +
 +#define IS_SYSTEM_POPUP(MenuInfo) \
 +      (0 != ((MenuInfo)->Flags & MF_POPUP) && 0 != ((MenuInfo)->Flags & MF_SYSMENU))
 +
 +#define IS_BITMAP_ITEM(flags) (MF_BITMAP == MENU_ITEM_TYPE(flags))
 +
 +/* Use global popup window because there's no way 2 menus can
 + * be tracked at the same time.  */
 +static HWND top_popup;
 +static HMENU top_popup_hmenu;
 +
 +/* Flag set by EndMenu() to force an exit from menu tracking */
 +static BOOL fEndMenu = FALSE;
 +
 +#define MENU_ITEM_HBMP_SPACE (5)
 +#define MENU_BAR_ITEMS_SPACE (12)
 +#define SEPARATOR_HEIGHT (5)
 +#define MENU_TAB_SPACE (8)
 +
 +typedef struct
 +{
 +  UINT  TrackFlags;
 +  HMENU CurrentMenu; /* current submenu (can be equal to hTopMenu)*/
 +  HMENU TopMenu;     /* initial menu */
 +  HWND  OwnerWnd;    /* where notifications are sent */
 +  POINT Pt;
 +} MTRACKER;
 +
 +
 +/*********************************************************************
 + * PopupMenu class descriptor
 + */
 +const struct builtin_class_descr POPUPMENU_builtin_class =
 +{
 +    WC_MENU,                     /* name */
 +    CS_SAVEBITS | CS_DBLCLKS,                  /* style  */
 +    (WNDPROC) NULL,                            /* FIXME - procA */
 +    (WNDPROC) PopupMenuWndProcW,               /* FIXME - procW */
 +    sizeof(MENUINFO *),                        /* extra */
 +    (LPCWSTR) IDC_ARROW,                       /* cursor */
 +    (HBRUSH)(COLOR_MENU + 1)                   /* brush */
 +};
 +
 +#ifndef GET_WORD
 +#define GET_WORD(ptr)  (*(WORD *)(ptr))
 +#endif
 +#ifndef GET_DWORD
 +#define GET_DWORD(ptr) (*(DWORD *)(ptr))
 +#endif
 +
 +HFONT hMenuFont = NULL;
 +HFONT hMenuFontBold = NULL;
 +
 +/* Dimension of the menu bitmaps */
 +static HBITMAP BmpSysMenu = NULL;
 +
 +static SIZE MenuCharSize;
 +
 +/***********************************************************************
 + *           MenuGetRosMenuInfo
 + *
 + * Get full information about menu
 + */
 +static BOOL FASTCALL
 +MenuGetRosMenuInfo(PROSMENUINFO MenuInfo, HMENU Menu)
 +{
 +  MenuInfo->cbSize = sizeof(ROSMENUINFO);
 +  MenuInfo->fMask = MIM_BACKGROUND | MIM_HELPID | MIM_MAXHEIGHT | MIM_MENUDATA | MIM_STYLE;
 +
 +  return NtUserMenuInfo(Menu, MenuInfo, FALSE);
 +}
 +
 +/***********************************************************************
 + *           MenuSetRosMenuInfo
 + *
 + * Set full information about menu
 + */
 +static BOOL FASTCALL
 +MenuSetRosMenuInfo(PROSMENUINFO MenuInfo)
 +{
 +  MenuInfo->cbSize = sizeof(ROSMENUINFO);
 +  MenuInfo->fMask = MIM_BACKGROUND | MIM_HELPID | MIM_MAXHEIGHT | MIM_MENUDATA | MIM_STYLE;
 +
 +  return NtUserMenuInfo(MenuInfo->Self, MenuInfo, TRUE);
 +}
 +
 +/***********************************************************************
 + *           MenuInitRosMenuItemInfo
 + *
 + * Initialize a buffer for use with MenuGet/SetRosMenuItemInfo
 + */
 +static VOID FASTCALL
 +MenuInitRosMenuItemInfo(PROSMENUITEMINFO ItemInfo)
 +{
 +  ZeroMemory(ItemInfo, sizeof(ROSMENUITEMINFO));
 +  ItemInfo->cbSize = sizeof(ROSMENUITEMINFO);
 +}
 +
 +/***********************************************************************
 + *           MenuGetRosMenuItemInfo
 + *
 + * Get full information about a menu item
 + */
 +static BOOL FASTCALL
 +MenuGetRosMenuItemInfo(HMENU Menu, UINT Index, PROSMENUITEMINFO ItemInfo)
 +{
 +  UINT Save_Mask = ItemInfo->fMask; /* Save the org mask bits. */
 +
 +  if (ItemInfo->dwTypeData != NULL)
 +    {
 +      HeapFree(GetProcessHeap(), 0, ItemInfo->dwTypeData);
 +    }
 +
 +
 +  ItemInfo->fMask = MIIM_BITMAP | MIIM_CHECKMARKS | MIIM_DATA | MIIM_FTYPE
 +             | MIIM_ID | MIIM_STATE | MIIM_STRING | MIIM_SUBMENU | MIIM_TYPE;
 +  ItemInfo->dwTypeData = NULL;
 +
 +  if (! NtUserMenuItemInfo(Menu, Index, TRUE, ItemInfo, FALSE))
 +    {
 +      ItemInfo->fType = 0;
 +      return FALSE;
 +    }
 +
 +  if (MENU_ITEM_TYPE(ItemInfo->fType) == MF_STRING)
 +    {
 +      ItemInfo->cch++;
 +      ItemInfo->dwTypeData = HeapAlloc(GetProcessHeap(), 0,
 +                                       ItemInfo->cch * sizeof(WCHAR));
 +      if (NULL == ItemInfo->dwTypeData)
 +        {
 +          return FALSE;
 +        }
 +
 +      if (! NtUserMenuItemInfo(Menu, Index, TRUE, ItemInfo, FALSE))
 +        {
 +          ItemInfo->fType = 0;
 +          return FALSE;
 +        }
 +      ItemInfo->dwTypeData[ItemInfo->cch - 1] = UNICODE_NULL;
 +    }
 +  ItemInfo->fMask =  Save_Mask;
 +  return TRUE;
 +}
 +
 +/***********************************************************************
 + *           MenuSetRosMenuItemInfo
 + *
 + * Set selected information about a menu item, need to set the mask bits.
 + */
 +static BOOL FASTCALL
 +MenuSetRosMenuItemInfo(HMENU Menu, UINT Index, PROSMENUITEMINFO ItemInfo)
 +{
 +  BOOL Ret;
 +
 +  if (MENU_ITEM_TYPE(ItemInfo->fType) == MF_STRING &&
 +      ItemInfo->dwTypeData != NULL)
 +  {
 +    ItemInfo->cch = strlenW(ItemInfo->dwTypeData);
 +  }
 +  Ret = NtUserMenuItemInfo(Menu, Index, TRUE, ItemInfo, TRUE);
 +
 +  return Ret;
 +}
 +
 +/***********************************************************************
 + *           MenuCleanupRosMenuItemInfo
 + *
 + * Cleanup after use of MenuGet/SetRosMenuItemInfo
 + */
 +static VOID FASTCALL
 +MenuCleanupRosMenuItemInfo(PROSMENUITEMINFO ItemInfo)
 +{
 +  if (ItemInfo->dwTypeData != NULL)
 +    {
 +      HeapFree(GetProcessHeap(), 0, ItemInfo->dwTypeData);
 +      ItemInfo->dwTypeData = NULL;
 +    }
 +}
 +
 +/***********************************************************************
 + *           MenuGetAllRosMenuItemInfo
 + *
 + * Get full information about all menu items
 + */
 +static INT FASTCALL
 +MenuGetAllRosMenuItemInfo(HMENU Menu, PROSMENUITEMINFO *ItemInfo)
 +{
 +  DWORD BufSize;
 +
 +  BufSize = NtUserBuildMenuItemList(Menu, (VOID *) 1, 0, 0);
 +  if (BufSize == (DWORD) -1 || BufSize == 0)
 +    {
 +      return -1;
 +    }
 +  *ItemInfo = HeapAlloc(GetProcessHeap(), 0, BufSize);
 +  if (NULL == *ItemInfo)
 +    {
 +      return -1;
 +    }
 +
 +  return NtUserBuildMenuItemList(Menu, *ItemInfo, BufSize, 0);
 +}
 +
 +/***********************************************************************
 + *           MenuCleanupAllRosMenuItemInfo
 + *
 + * Cleanup after use of MenuGetAllRosMenuItemInfo
 + */
 +static VOID FASTCALL
 +MenuCleanupAllRosMenuItemInfo(PROSMENUITEMINFO ItemInfo)
 +{
 +  HeapFree(GetProcessHeap(), 0, ItemInfo);
 +}
 +
 +/***********************************************************************
 + *           MenuInitSysMenuPopup
 + *
 + * Grey the appropriate items in System menu.
 + */
 +void FASTCALL MenuInitSysMenuPopup(HMENU hmenu, DWORD style, DWORD clsStyle, LONG HitTest )
 +{
 +    BOOL gray;
 +    UINT DefItem;
 +    #if 0
 +    MENUITEMINFOW mii;
 +    #endif
 +
 +    gray = !(style & WS_THICKFRAME) || (style & (WS_MAXIMIZE | WS_MINIMIZE));
 +    EnableMenuItem( hmenu, SC_SIZE, (gray ? MF_GRAYED : MF_ENABLED) );
 +    gray = ((style & WS_MAXIMIZE) != 0);
 +    EnableMenuItem( hmenu, SC_MOVE, (gray ? MF_GRAYED : MF_ENABLED) );
 +    gray = !(style & WS_MINIMIZEBOX) || (style & WS_MINIMIZE);
 +    EnableMenuItem( hmenu, SC_MINIMIZE, (gray ? MF_GRAYED : MF_ENABLED) );
 +    gray = !(style & WS_MAXIMIZEBOX) || (style & WS_MAXIMIZE);
 +    EnableMenuItem( hmenu, SC_MAXIMIZE, (gray ? MF_GRAYED : MF_ENABLED) );
 +    gray = !(style & (WS_MAXIMIZE | WS_MINIMIZE));
 +    EnableMenuItem( hmenu, SC_RESTORE, (gray ? MF_GRAYED : MF_ENABLED) );
 +    gray = (clsStyle & CS_NOCLOSE) != 0;
 +
 +    /* The menu item must keep its state if it's disabled */
 +    if(gray)
 +        EnableMenuItem( hmenu, SC_CLOSE, MF_GRAYED);
 +
 +    /* Set default menu item */
 +    if(style & WS_MINIMIZE) DefItem = SC_RESTORE;
 +    else if(HitTest == HTCAPTION) DefItem = ((style & (WS_MAXIMIZE | WS_MINIMIZE)) ? SC_RESTORE : SC_MAXIMIZE);
 +    else DefItem = SC_CLOSE;
 +#if 0
 +    mii.cbSize = sizeof(MENUITEMINFOW);
 +    mii.fMask |= MIIM_STATE;
 +    if((DefItem != SC_CLOSE) && GetMenuItemInfoW(hmenu, DefItem, FALSE, &mii) &&
 +       (mii.fState & (MFS_GRAYED | MFS_DISABLED))) DefItem = SC_CLOSE;
 +#endif
 +    SetMenuDefaultItem(hmenu, DefItem, MF_BYCOMMAND);
 +}
 +
 +/******************************************************************************
 + *
 + *   UINT MenuGetStartOfNextColumn(
 + *     PROSMENUINFO MenuInfo)
 + *
 + *****************************************************************************/
 +static UINT MenuGetStartOfNextColumn(
 +    PROSMENUINFO MenuInfo)
 +{
 +    PROSMENUITEMINFO MenuItems;
 +    UINT i;
 +
 +    i = MenuInfo->FocusedItem;
 +    if ( i == NO_SELECTED_ITEM )
 +        return i;
 +
 +    if (MenuGetAllRosMenuItemInfo(MenuInfo->Self, &MenuItems) <= 0)
 +        return NO_SELECTED_ITEM;
 +
 +    for (i++ ; i < MenuInfo->MenuItemCount; i++)
 +        if (0 != (MenuItems[i].fType & (MF_MENUBREAK | MF_MENUBARBREAK)))
 +            return i;
 +
 +    return NO_SELECTED_ITEM;
 +}
 +
 +/******************************************************************************
 + *
 + *   UINT MenuGetStartOfPrevColumn(
 + *     PROSMENUINFO MenuInfo)
 + *
 + *****************************************************************************/
 +
 +static UINT FASTCALL MenuGetStartOfPrevColumn(
 +    PROSMENUINFO MenuInfo)
 +{
 +    PROSMENUITEMINFO MenuItems;
 +    UINT i;
 +
 +    if (!MenuInfo->FocusedItem || MenuInfo->FocusedItem == NO_SELECTED_ITEM)
 +        return NO_SELECTED_ITEM;
 +
 +    if (MenuGetAllRosMenuItemInfo(MenuInfo->Self, &MenuItems) <= 0)
 +        return NO_SELECTED_ITEM;
 +
 +    /* Find the start of the column */
 +    for (i = MenuInfo->FocusedItem;
 +         0 != i && 0 == (MenuItems[i].fType & (MF_MENUBREAK | MF_MENUBARBREAK));
 +         --i)
 +    {
 +        ; /* empty */
 +    }
 +
 +    if (i == 0)
 +    {
 +        MenuCleanupAllRosMenuItemInfo(MenuItems);
 +        return NO_SELECTED_ITEM;
 +    }
 +
 +    for (--i; 0 != i; --i)
 +        if (MenuItems[i].fType & (MF_MENUBREAK | MF_MENUBARBREAK))
 +            break;
 +
 +    MenuCleanupAllRosMenuItemInfo(MenuItems);
 +    TRACE("ret %d.\n", i );
 +
 +    return i;
 +}
 +
 +/***********************************************************************
 + *           MenuFindSubMenu
 + *
 + * Find a Sub menu. Return the position of the submenu, and modifies
 + * *hmenu in case it is found in another sub-menu.
 + * If the submenu cannot be found, NO_SELECTED_ITEM is returned.
 + */
 +static UINT FASTCALL MenuFindSubMenu(HMENU *hmenu, HMENU hSubTarget )
 +{
 +    ROSMENUINFO menu;
 +    UINT i;
 +    ROSMENUITEMINFO item;
 +    if (((*hmenu)==(HMENU)0xffff) ||
 +          (!MenuGetRosMenuInfo(&menu, *hmenu)))
 +        return NO_SELECTED_ITEM;
 +
 +    MenuInitRosMenuItemInfo(&item);
 +    for (i = 0; i < menu.MenuItemCount; i++) {
 +        if (! MenuGetRosMenuItemInfo(menu.Self, i, &item))
 +        {
 +            MenuCleanupRosMenuItemInfo(&item);
 +            return NO_SELECTED_ITEM;
 +        }
 +        if (!(item.fType & MF_POPUP)) continue;
 +        if (item.hSubMenu == hSubTarget) {
 +            MenuCleanupRosMenuItemInfo(&item);
 +            return i;
 +        }
 +        else  {
 +            HMENU hsubmenu = item.hSubMenu;
 +            UINT pos = MenuFindSubMenu(&hsubmenu, hSubTarget );
 +            if (pos != NO_SELECTED_ITEM) {
 +                *hmenu = hsubmenu;
 +                return pos;
 +           }
 +        }
 +    }
 +    MenuCleanupRosMenuItemInfo(&item);
 +    return NO_SELECTED_ITEM;
 +}
 +
 +/***********************************************************************
 + *           MenuLoadBitmaps
 + *
 + * Load the arrow bitmap. We can't do this from MenuInit since user32
 + * can also be used (and thus initialized) from text-mode.
 + */
 +static void FASTCALL
 +MenuLoadBitmaps(VOID)
 +{
 +  /* Load system buttons bitmaps */
 +  if (NULL == BmpSysMenu)
 +    {
 +      BmpSysMenu = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CLOSE));
 +    }
 +}
 +
 +/***********************************************************************
 + *           MenuDrawPopupGlyph
 + *
 + * Draws popup magic glyphs (can be found in system menu).
 + */
 +static void FASTCALL
 +MenuDrawPopupGlyph(HDC dc, LPRECT r, INT_PTR popupMagic, BOOL inactive, BOOL hilite)
 +{
 +  LOGFONTW lf;
 +  HFONT hFont, hOldFont;
 +  COLORREF clrsave;
 +  INT bkmode;
 +  TCHAR symbol;
 +  switch (popupMagic)
 +  {
 +  case (INT_PTR) HBMMENU_POPUP_RESTORE:
 +    symbol = '2';
 +    break;
 +  case (INT_PTR) HBMMENU_POPUP_MINIMIZE:
 +    symbol = '0';
 +    break;
 +  case (INT_PTR) HBMMENU_POPUP_MAXIMIZE:
 +    symbol = '1';
 +    break;
 +  case (INT_PTR) HBMMENU_POPUP_CLOSE:
 +    symbol = 'r';
 +    break;
 +  default:
 +    ERR("Invalid popup magic bitmap %d\n", (int)popupMagic);
 +    return;
 +  }
 +  ZeroMemory(&lf, sizeof(LOGFONTW));
 +  InflateRect(r, -2, -2);
 +  lf.lfHeight = r->bottom - r->top;
 +  lf.lfWidth = 0;
 +  lf.lfWeight = FW_NORMAL;
 +  lf.lfCharSet = DEFAULT_CHARSET;
 +  lstrcpy(lf.lfFaceName, TEXT("Marlett"));
 +  hFont = CreateFontIndirect(&lf);
 +  /* save font and text color */
 +  hOldFont = SelectObject(dc, hFont);
 +  clrsave = GetTextColor(dc);
 +  bkmode = GetBkMode(dc);
 +  /* set color and drawing mode */
 +  SetBkMode(dc, TRANSPARENT);
 +  if (inactive)
 +  {
 +    /* draw shadow */
 +    if (!hilite)
 +    {
 +      SetTextColor(dc, GetSysColor(COLOR_HIGHLIGHTTEXT));
 +      TextOut(dc, r->left + 1, r->top + 1, &symbol, 1);
 +    }
 +  }
 +  SetTextColor(dc, GetSysColor(inactive ? COLOR_GRAYTEXT : (hilite ? COLOR_HIGHLIGHTTEXT : COLOR_MENUTEXT)));
 +  /* draw selected symbol */
 +  TextOut(dc, r->left, r->top, &symbol, 1);
 +  /* restore previous settings */
 +  SetTextColor(dc, clrsave);
 +  SelectObject(dc, hOldFont);
 +  SetBkMode(dc, bkmode);
 +  DeleteObject(hFont);
 +}
 +
 +/***********************************************************************
 + *           MenuFindItemByKey
 + *
 + * Find the menu item selected by a key press.
 + * Return item id, -1 if none, -2 if we should close the menu.
 + */
 +static UINT FASTCALL MenuFindItemByKey(HWND WndOwner, PROSMENUINFO MenuInfo,
 +                  WCHAR Key, BOOL ForceMenuChar)
 +{
 +  ROSMENUINFO SysMenuInfo;
 +  PROSMENUITEMINFO Items, ItemInfo;
 +  LRESULT MenuChar;
 +  UINT i;
 +
 +  TRACE("\tlooking for '%c' (0x%02x) in [%p]\n", (char) Key, Key, MenuInfo);
 +
 +  if (NULL == MenuInfo || ! IsMenu(MenuInfo->Self))
 +    {
 +      if (MenuGetRosMenuInfo(&SysMenuInfo, GetSystemMenu(WndOwner, FALSE)))
 +        {
 +          MenuInfo = &SysMenuInfo;
 +        }
 +      else
 +        {
 +          MenuInfo = NULL;
 +        }
 +    }
 +
 +  if (NULL != MenuInfo)
 +    {
 +      if (MenuGetAllRosMenuItemInfo(MenuInfo->Self, &Items) <= 0)
 +        {
 +          return -1;
 +        }
 +      if (! ForceMenuChar)
 +        {
 +          Key = toupperW(Key);
 +          ItemInfo = Items;
 +          for (i = 0; i < MenuInfo->MenuItemCount; i++, ItemInfo++)
 +            {
 +              if ((ItemInfo->lpstr) && NULL != ItemInfo->dwTypeData)
 +                {
 +                  WCHAR *p = (WCHAR *) ItemInfo->dwTypeData - 2;
 +                  do
 +                    {
 +                      p = strchrW(p + 2, '&');
 +                  }
 +                  while (NULL != p && L'&' == p[1]);
 +                  if (NULL != p && (toupperW(p[1]) == Key))
 +                    {
 +                      return i;
 +                    }
 +                }
 +            }
 +        }
 +
 +      MenuChar = SendMessageW(WndOwner, WM_MENUCHAR,
 +                              MAKEWPARAM(Key, MenuInfo->Flags), (LPARAM) MenuInfo->Self);
 +      if (2 == HIWORD(MenuChar))
 +        {
 +          return LOWORD(MenuChar);
 +        }
 +      if (1 == HIWORD(MenuChar))
 +        {
 +          return (UINT) (-2);
 +        }
 +    }
 +
 +  return (UINT)(-1);
 +}
 +
 +/***********************************************************************
 + *           MenuGetBitmapItemSize
 + *
 + * Get the size of a bitmap item.
 + */
 +static void FASTCALL MenuGetBitmapItemSize(PROSMENUITEMINFO lpitem, SIZE *size, HWND WndOwner)
 +{
 +    BITMAP bm;
 +    HBITMAP bmp = lpitem->hbmpItem;
 +
 +    size->cx = size->cy = 0;
 +
 +    /* check if there is a magic menu item associated with this item */
 +    if (IS_MAGIC_BITMAP(bmp))
 +    {
 +      switch((INT_PTR) bmp)
 +        {
 +            case (INT_PTR)HBMMENU_CALLBACK:
 +            {
 +                MEASUREITEMSTRUCT measItem;
 +                measItem.CtlType = ODT_MENU;
 +                measItem.CtlID = 0;
 +                measItem.itemID = lpitem->wID;
 +                measItem.itemWidth = lpitem->Rect.right - lpitem->Rect.left;
 +                measItem.itemHeight = lpitem->Rect.bottom - lpitem->Rect.top;
 +                measItem.itemData = lpitem->dwItemData;
 +                SendMessageW( WndOwner, WM_MEASUREITEM, lpitem->wID, (LPARAM)&measItem);
 +                size->cx = measItem.itemWidth;
 +                size->cy = measItem.itemHeight;
 +                return;
 +            }
 +            break;
 +
 +          case (INT_PTR) HBMMENU_SYSTEM:
 +            if (0 != lpitem->dwItemData)
 +              {
 +                bmp = (HBITMAP) lpitem->dwItemData;
 +                break;
 +              }
 +            /* fall through */
 +          case (INT_PTR) HBMMENU_MBAR_RESTORE:
 +          case (INT_PTR) HBMMENU_MBAR_MINIMIZE:
 +          case (INT_PTR) HBMMENU_MBAR_CLOSE:
 +          case (INT_PTR) HBMMENU_MBAR_MINIMIZE_D:
 +          case (INT_PTR) HBMMENU_MBAR_CLOSE_D:
 +          case (INT_PTR) HBMMENU_POPUP_CLOSE:
 +          case (INT_PTR) HBMMENU_POPUP_RESTORE:
 +          case (INT_PTR) HBMMENU_POPUP_MAXIMIZE:
 +          case (INT_PTR) HBMMENU_POPUP_MINIMIZE:
 +            /* FIXME: Why we need to subtract these magic values? */
 +            /* to make them smaller than the menu bar? */
 +            size->cx = GetSystemMetrics(SM_CXSIZE) - 2;
 +            size->cy = GetSystemMetrics(SM_CYSIZE) - 4;
 +            return;
 +        }
 +    }
 +
 +    if (GetObjectW(bmp, sizeof(BITMAP), &bm))
 +    {
 +        size->cx = bm.bmWidth;
 +        size->cy = bm.bmHeight;
 +    }
 +}
 +
 +/***********************************************************************
 + *           MenuDrawBitmapItem
 + *
 + * Draw a bitmap item.
 + */
 +static void FASTCALL MenuDrawBitmapItem(HDC hdc, PROSMENUITEMINFO lpitem, const RECT *rect,
 +                    HMENU hmenu, HWND WndOwner, UINT odaction, BOOL MenuBar)
 +{
 +    BITMAP bm;
 +    DWORD rop;
 +    HDC hdcMem;
 +    HBITMAP bmp;
 +    int w = rect->right - rect->left;
 +    int h = rect->bottom - rect->top;
 +    int bmp_xoffset = 0;
 +    int left, top;
 +    HBITMAP hbmToDraw = lpitem->hbmpItem;
 +    bmp = hbmToDraw;
 +
 +    /* Check if there is a magic menu item associated with this item */
 +    if (IS_MAGIC_BITMAP(hbmToDraw))
 +    {
 +        UINT flags = 0;
 +        RECT r;
 +
 +      r = *rect;
 +      switch ((INT_PTR)hbmToDraw)
 +        {
 +        case (INT_PTR)HBMMENU_SYSTEM:
 +            if (lpitem->dwTypeData)
 +            {
 +                bmp = (HBITMAP)lpitem->dwTypeData;
 +                if (!GetObjectW( bmp, sizeof(bm), &bm )) return;
 +            }
 +            else
 +            {
 +                if (!BmpSysMenu) BmpSysMenu = LoadBitmapW(0, MAKEINTRESOURCEW(OBM_CLOSE));
 +                bmp = BmpSysMenu;
 +                if (! GetObjectW(bmp, sizeof(bm), &bm)) return;
 +                /* only use right half of the bitmap */
 +                bmp_xoffset = bm.bmWidth / 2;
 +                bm.bmWidth -= bmp_xoffset;
 +            }
 +            goto got_bitmap;
 +        case (INT_PTR)HBMMENU_MBAR_RESTORE:
 +            flags = DFCS_CAPTIONRESTORE;
 +            break;
 +        case (INT_PTR)HBMMENU_MBAR_MINIMIZE:
 +            r.right += 1;
 +            flags = DFCS_CAPTIONMIN;
 +            break;
 +        case (INT_PTR)HBMMENU_MBAR_MINIMIZE_D:
 +            r.right += 1;
 +            flags = DFCS_CAPTIONMIN | DFCS_INACTIVE;
 +            break;
 +        case (INT_PTR)HBMMENU_MBAR_CLOSE:
 +            flags = DFCS_CAPTIONCLOSE;
 +            break;
 +        case (INT_PTR)HBMMENU_MBAR_CLOSE_D:
 +            flags = DFCS_CAPTIONCLOSE | DFCS_INACTIVE;
 +            break;
 +        case (INT_PTR)HBMMENU_CALLBACK:
 +            {
 +                DRAWITEMSTRUCT drawItem;
 +                POINT origorg;
 +                drawItem.CtlType = ODT_MENU;
 +                drawItem.CtlID = 0;
 +                drawItem.itemID = lpitem->wID;
 +                drawItem.itemAction = odaction;
 +                drawItem.itemState = (lpitem->fState & MF_CHECKED)?ODS_CHECKED:0;
 +                drawItem.itemState |= (lpitem->fState & MF_DEFAULT)?ODS_DEFAULT:0;
 +                drawItem.itemState |= (lpitem->fState & MF_DISABLED)?ODS_DISABLED:0;
 +                drawItem.itemState |= (lpitem->fState & MF_GRAYED)?ODS_GRAYED|ODS_DISABLED:0;
 +                drawItem.itemState |= (lpitem->fState & MF_HILITE)?ODS_SELECTED:0;
 +                drawItem.hwndItem = (HWND)hmenu;
 +                drawItem.hDC = hdc;
 +                drawItem.rcItem = *rect;
 +                drawItem.itemData = lpitem->dwItemData;
 +                /* some applications make this assumption on the DC's origin */
 +                SetViewportOrgEx( hdc, lpitem->Rect.left, lpitem->Rect.top, &origorg);
 +                OffsetRect( &drawItem.rcItem, - lpitem->Rect.left, - lpitem->Rect.top);
 +                SendMessageW( WndOwner, WM_DRAWITEM, 0, (LPARAM)&drawItem);
 +                SetViewportOrgEx( hdc, origorg.x, origorg.y, NULL);
 +                return;
 +            }
 +            break;
 +
 +          case (INT_PTR) HBMMENU_POPUP_CLOSE:
 +          case (INT_PTR) HBMMENU_POPUP_RESTORE:
 +          case (INT_PTR) HBMMENU_POPUP_MAXIMIZE:
 +          case (INT_PTR) HBMMENU_POPUP_MINIMIZE:
 +            MenuDrawPopupGlyph(hdc, &r, (INT_PTR)hbmToDraw, lpitem->fState & MF_GRAYED, lpitem->fState & MF_HILITE);
 +            return;
 +        }
 +      InflateRect(&r, -1, -1);
 +      if (0 != (lpitem->fState & MF_HILITE))
 +      {
 +          flags |= DFCS_PUSHED;
 +      }
 +      DrawFrameControl(hdc, &r, DFC_CAPTION, flags);
 +      return;
 +    }
 +
 +    if (!bmp || !GetObjectW( bmp, sizeof(bm), &bm )) return;
 +
 + got_bitmap:
 +    hdcMem = CreateCompatibleDC( hdc );
 +    SelectObject( hdcMem, bmp );
 +
 +    /* handle fontsize > bitmap_height */
 +    top = (h>bm.bmHeight) ? rect->top+(h-bm.bmHeight)/2 : rect->top;
 +    left=rect->left;
 +    rop=((lpitem->fState & MF_HILITE) && !IS_MAGIC_BITMAP(hbmToDraw)) ? NOTSRCCOPY : SRCCOPY;
 +    if ((lpitem->fState & MF_HILITE) && lpitem->hbmpItem)
 +        SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
 +    BitBlt( hdc, left, top, w, h, hdcMem, bmp_xoffset, 0, rop );
 +    DeleteDC( hdcMem );
 +}
 +
 +/***********************************************************************
 + *           MenuCalcItemSize
 + *
 + * Calculate the size of the menu item and store it in lpitem->rect.
 + */
 +static void FASTCALL MenuCalcItemSize( HDC hdc, PROSMENUITEMINFO lpitem, PROSMENUINFO MenuInfo, HWND hwndOwner,
 +                 INT orgX, INT orgY, BOOL menuBar)
 +{
 +    WCHAR *p;
 +    UINT check_bitmap_width = GetSystemMetrics( SM_CXMENUCHECK );
 +    INT itemheight = 0;
 +
 +    TRACE("dc=%x owner=%x (%d,%d)\n", hdc, hwndOwner, orgX, orgY);
 +
 +    MenuCharSize.cx = GdiGetCharDimensions( hdc, NULL, &MenuCharSize.cy );
 +
 +    SetRect( &lpitem->Rect, orgX, orgY, orgX, orgY );
 +
 +    if (lpitem->fType & MF_OWNERDRAW)
 +    {
 +        MEASUREITEMSTRUCT mis;
 +        mis.CtlType    = ODT_MENU;
 +        mis.CtlID      = 0;
 +        mis.itemID     = lpitem->wID;
 +        mis.itemData   = lpitem->dwItemData;
 +        mis.itemHeight = HIWORD( GetDialogBaseUnits());
 +        mis.itemWidth  = 0;
 +        SendMessageW( hwndOwner, WM_MEASUREITEM, 0, (LPARAM)&mis );
 +        /* Tests reveal that Windows ( Win95 thru WinXP) adds twice the average
 +         * width of a menufont character to the width of an owner-drawn menu.
 +         */
 +        lpitem->Rect.right += mis.itemWidth + 2 * MenuCharSize.cx;
 +
 +        if (menuBar) {
 +            /* under at least win95 you seem to be given a standard
 +               height for the menu and the height value is ignored */
 +            lpitem->Rect.bottom += GetSystemMetrics(SM_CYMENUSIZE);
 +        } else
 +            lpitem->Rect.bottom += mis.itemHeight;
 +
 +        TRACE("id=%04lx size=%dx%d\n",
 +                lpitem->wID, mis.itemWidth, mis.itemHeight);
 +        return;
 +    }
 +
 +    if (lpitem->fType & MF_SEPARATOR)
 +    {
 +        lpitem->Rect.bottom += SEPARATOR_HEIGHT;
 +        if( !menuBar)
 +            lpitem->Rect.right += check_bitmap_width +  MenuCharSize.cx;
 +        return;
 +    }
 +
 +    lpitem->dxTab = 0;
 +
 +    if (lpitem->hbmpItem)
 +    {
 +        SIZE size;
 +
 +        if (!menuBar) {
 +            MenuGetBitmapItemSize(lpitem, &size, hwndOwner );
 +            /* Keep the size of the bitmap in callback mode to be able
 +             * to draw it correctly */
 +            lpitem->Rect.right = lpitem->Rect.left + size.cx;
 +            if (MenuInfo->maxBmpSize.cx < abs(size.cx) +  MENU_ITEM_HBMP_SPACE ||
 +                MenuInfo->maxBmpSize.cy < abs(size.cy))
 +            {
 +                MenuInfo->maxBmpSize.cx = abs(size.cx) + MENU_ITEM_HBMP_SPACE;
 +                MenuInfo->maxBmpSize.cy = abs(size.cy);
 +            }
 +            MenuSetRosMenuInfo(MenuInfo);
 +            itemheight = size.cy + 2;
 +
 +            if( !(MenuInfo->dwStyle & MNS_NOCHECK))
 +                lpitem->Rect.right += 2 * check_bitmap_width;
 +            lpitem->Rect.right += 4 + MenuCharSize.cx;
 +            lpitem->dxTab = lpitem->Rect.right;
 +            lpitem->Rect.right += check_bitmap_width;
 +        } else /* hbmpItem & MenuBar */ {
 +            MenuGetBitmapItemSize(lpitem, &size, hwndOwner );
 +            lpitem->Rect.right  += size.cx;
 +            if( lpitem->lpstr) lpitem->Rect.right  += 2;
 +            itemheight = size.cy;
 +
 +            /* Special case: Minimize button doesn't have a space behind it. */
 +            if (lpitem->hbmpItem == (HBITMAP)HBMMENU_MBAR_MINIMIZE ||
 +                lpitem->hbmpItem == (HBITMAP)HBMMENU_MBAR_MINIMIZE_D)
 +            lpitem->Rect.right -= 1;
 +        }
 +    }
 +    else if (!menuBar) {
 +        if( !(MenuInfo->dwStyle & MNS_NOCHECK))
 +             lpitem->Rect.right += check_bitmap_width;
 +        lpitem->Rect.right += 4 + MenuCharSize.cx;
 +        lpitem->dxTab = lpitem->Rect.right;
 +        lpitem->Rect.right += check_bitmap_width;
 +    }
 +
 +    /* it must be a text item - unless it's the system menu */
 +    if (!(lpitem->fType & MF_SYSMENU) && lpitem->lpstr) {
 +        HFONT hfontOld = NULL;
 +        RECT rc = lpitem->Rect;
 +        LONG txtheight, txtwidth;
 +
 +        if ( lpitem->fState & MFS_DEFAULT ) {
 +            hfontOld = SelectObject( hdc, hMenuFontBold );
 +        }
 +        if (menuBar) {
 +            txtheight = DrawTextW( hdc, lpitem->dwTypeData, -1, &rc,
 +                    DT_SINGLELINE|DT_CALCRECT);
 +            lpitem->Rect.right  += rc.right - rc.left;
 +            itemheight = max( max( itemheight, txtheight),
 +                    GetSystemMetrics( SM_CYMENU) - 1);
 +            lpitem->Rect.right +=  2 * MenuCharSize.cx;
 +        } else {
 +            if ((p = strchrW( lpitem->dwTypeData, '\t' )) != NULL) {
 +                RECT tmprc = rc;
 +                LONG tmpheight;
 +                int n = (int)( p - lpitem->dwTypeData);
 +                /* Item contains a tab (only meaningful in popup menus) */
 +                /* get text size before the tab */
 +                txtheight = DrawTextW( hdc, lpitem->dwTypeData, n, &rc,
 +                        DT_SINGLELINE|DT_CALCRECT);
 +                txtwidth = rc.right - rc.left;
 +                p += 1; /* advance past the Tab */
 +                /* get text size after the tab */
 +                tmpheight = DrawTextW( hdc, p, -1, &tmprc,
 +                        DT_SINGLELINE|DT_CALCRECT);
 +                lpitem->dxTab += txtwidth;
 +                txtheight = max( txtheight, tmpheight);
 +                txtwidth += MenuCharSize.cx + /* space for the tab */
 +                    tmprc.right - tmprc.left; /* space for the short cut */
 +            } else {
 +                txtheight = DrawTextW( hdc, lpitem->dwTypeData, -1, &rc,
 +                        DT_SINGLELINE|DT_CALCRECT);
 +                txtwidth = rc.right - rc.left;
 +                lpitem->dxTab += txtwidth;
 +            }
 +            lpitem->Rect.right  += 2 + txtwidth;
 +            itemheight = max( itemheight,
 +                                  max( txtheight + 2, MenuCharSize.cy + 4));
 +        }
 +        if (hfontOld) SelectObject (hdc, hfontOld);
 +    } else if( menuBar) {
 +        itemheight = max( itemheight, GetSystemMetrics(SM_CYMENU)-1);
 +    }
 +    lpitem->Rect.bottom += itemheight;
 +    TRACE("(%ld,%ld)-(%ld,%ld)\n", lpitem->Rect.left, lpitem->Rect.top, lpitem->Rect.right, lpitem->Rect.bottom);
 +}
 +
 +/***********************************************************************
 + *           MenuPopupMenuCalcSize
 + *
 + * Calculate the size of a popup menu.
 + */
 +static void FASTCALL MenuPopupMenuCalcSize(PROSMENUINFO MenuInfo, HWND WndOwner)
 +{
 +    ROSMENUITEMINFO lpitem;
 +    HDC hdc;
 +    int start, i;
 +    int orgX, orgY, maxX, maxTab, maxTabWidth;
 +
 +    MenuInfo->Width = MenuInfo->Height = 0;
 +    if (MenuInfo->MenuItemCount == 0)
 +    {
 +        MenuSetRosMenuInfo(MenuInfo);
 +        return;
 +    }
 +
 +    hdc = GetDC(NULL);
 +    SelectObject( hdc, hMenuFont );
 +
 +    start = 0;
 +    maxX = 2 + 1;
 +
 +    MenuInfo->maxBmpSize.cx = 0;
 +    MenuInfo->maxBmpSize.cy = 0;
 +
 +    MenuInitRosMenuItemInfo(&lpitem);
 +    while (start < MenuInfo->MenuItemCount)
 +    {
 +      orgX = maxX;
 +      orgY = 2;
 +
 +      maxTab = maxTabWidth = 0;
 +
 +      /* Parse items until column break or end of menu */
 +      for (i = start; i < MenuInfo->MenuItemCount; i++)
 +      {
 +          if (! MenuGetRosMenuItemInfo(MenuInfo->Self, i, &lpitem))
 +          {
 +              MenuCleanupRosMenuItemInfo(&lpitem);
 +              MenuSetRosMenuInfo(MenuInfo);
 +              return;
 +          }
 +          if (i != start &&
 +               (lpitem.fType & (MF_MENUBREAK | MF_MENUBARBREAK))) break;
 +
 +          MenuCalcItemSize(hdc, &lpitem, MenuInfo, WndOwner, orgX, orgY, FALSE);
 +          if (! MenuSetRosMenuItemInfo(MenuInfo->Self, i, &lpitem))
 +          {
 +              MenuCleanupRosMenuItemInfo(&lpitem);
 +              MenuSetRosMenuInfo(MenuInfo);
 +              return;
 +          }
 +// Not sure here,, The patch from wine removes this.
 +//        if ((lpitem.fType & MF_MENUBARBREAK) != 0)
 +//        {
 +//              OrgX++;
 +//        }
 +          maxX = max(maxX, lpitem.Rect.right);
 +          orgY = lpitem.Rect.bottom;
 +          if ((lpitem.lpstr) && lpitem.dxTab )
 +            {
 +              maxTab = max( maxTab, lpitem.dxTab );
 +              maxTabWidth = max(maxTabWidth, lpitem.Rect.right - lpitem.dxTab);
 +          }
 +        }
 +
 +        /* Finish the column (set all items to the largest width found) */
 +        maxX = max( maxX, maxTab + maxTabWidth );
 +        while (start < i)
 +        {
 +            if (MenuGetRosMenuItemInfo(MenuInfo->Self, start, &lpitem))
 +            {
 +                lpitem.Rect.right = maxX;
 +                if ((lpitem.lpstr) && 0 != lpitem.dxTab)
 +                {
 +                    lpitem.dxTab = maxTab;
 +                }
 +                MenuSetRosMenuItemInfo(MenuInfo->Self, start, &lpitem);
 +            }
 +            start++;
 +          }
 +        MenuInfo->Height = max(MenuInfo->Height, orgY);
 +    }
 +
 +    MenuInfo->Width  = maxX;
 +
 +    /* space for 3d border */
 +    MenuInfo->Height += 2;
 +    MenuInfo->Width += 2;
 +
 +    MenuCleanupRosMenuItemInfo(&lpitem);
 +    MenuSetRosMenuInfo(MenuInfo);
 +    ReleaseDC( 0, hdc );
 +}
 +
 +/***********************************************************************
 + *           MenuMenuBarCalcSize
 + *
 + * FIXME: Word 6 implements its own MDI and its own 'close window' bitmap
 + * height is off by 1 pixel which causes lengthy window relocations when
 + * active document window is maximized/restored.
 + *
 + * Calculate the size of the menu bar.
 + */
 +static void FASTCALL MenuMenuBarCalcSize( HDC hdc, LPRECT lprect,
 +                                          PROSMENUINFO MenuInfo, HWND hwndOwner )
 +{
 +    ROSMENUITEMINFO ItemInfo;
 +    int start, i, orgX, orgY, maxY, helpPos;
 +
 +    if ((lprect == NULL) || (MenuInfo == NULL)) return;
 +    if (MenuInfo->MenuItemCount == 0) return;
 +    TRACE("left=%ld top=%ld right=%ld bottom=%ld\n", lprect->left, lprect->top, lprect->right, lprect->bottom);
 +    MenuInfo->Width = lprect->right - lprect->left;
 +    MenuInfo->Height = 0;
 +    maxY = lprect->top + 1;
 +    start = 0;
 +    helpPos = -1;
 +
 +    MenuInfo->maxBmpSize.cx = 0;
 +    MenuInfo->maxBmpSize.cy = 0;
 +
 +    MenuInitRosMenuItemInfo(&ItemInfo);
 +    while (start < MenuInfo->MenuItemCount)
 +    {
 +        if (! MenuGetRosMenuItemInfo(MenuInfo->Self, start, &ItemInfo))
 +        {
 +            MenuCleanupRosMenuItemInfo(&ItemInfo);
 +            return;
 +        }
 +        orgX = lprect->left;
 +        orgY = maxY;
 +
 +        /* Parse items until line break or end of menu */
 +        for (i = start; i < MenuInfo->MenuItemCount; i++)
 +          {
 +            if ((helpPos == -1) && (ItemInfo.fType & MF_RIGHTJUSTIFY)) helpPos = i;
 +            if ((i != start) &&
 +               (ItemInfo.fType & (MF_MENUBREAK | MF_MENUBARBREAK))) break;
 +
 +            TRACE("calling MENU_CalcItemSize org=(%d, %d)\n", orgX, orgY);
 +            MenuCalcItemSize(hdc, &ItemInfo, MenuInfo, hwndOwner, orgX, orgY, TRUE);
 +            if (! MenuSetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo))
 +            {
 +                MenuCleanupRosMenuItemInfo(&ItemInfo);
 +                return;
 +            }
 +
 +            if (ItemInfo.Rect.right > lprect->right)
 +            {
 +                if (i != start) break;
 +                else ItemInfo.Rect.right = lprect->right;
 +            }
 +            maxY = max( maxY, ItemInfo.Rect.bottom );
 +            orgX = ItemInfo.Rect.right;
 +            if (i + 1 < MenuInfo->MenuItemCount)
 +            {
 +                if (! MenuGetRosMenuItemInfo(MenuInfo->Self, i + 1, &ItemInfo))
 +                {
 +                    MenuCleanupRosMenuItemInfo(&ItemInfo);
 +                    return;
 +                }
 +            }
 +      }
 +
 +/* FIXME: Is this really needed? */ /*NO! it is not needed, why make the
 +HBMMENU_MBAR_CLOSE, MINIMIZE & RESTORE, look the same size as the menu bar! */
 +#if 0
 +        /* Finish the line (set all items to the largest height found) */
 +        while (start < i)
 +        {
 +            if (MenuGetRosMenuItemInfo(MenuInfo->Self, start, &ItemInfo))
 +            {
 +                ItemInfo.Rect.bottom = maxY;
 +                MenuSetRosMenuItemInfo(MenuInfo->Self, start, &ItemInfo);
 +            }
 +            start++;
 +        }
 +#else
 +        start = i; /* This works! */
 +#endif
 +    }
 +
 +    lprect->bottom = maxY;
 +    MenuInfo->Height = lprect->bottom - lprect->top;
 +    MenuSetRosMenuInfo(MenuInfo);
 +
 +    if (helpPos != -1)
 +    {
 +      /* Flush right all items between the MF_RIGHTJUSTIFY and */
 +      /* the last item (if several lines, only move the last line) */
 +      if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->MenuItemCount - 1, &ItemInfo))
 +      {
 +          MenuCleanupRosMenuItemInfo(&ItemInfo);
 +          return;
 +      }
 +      orgY = ItemInfo.Rect.top;
 +      orgX = lprect->right;
 +      for (i = MenuInfo->MenuItemCount - 1; helpPos <= i; i--)
 +        {
 +          if (i < helpPos)
 +          {
 +              break;                          /* done */
 +          }
 +          if (ItemInfo.Rect.top != orgY)
 +          {
 +              break;                          /* Other line */
 +          }
 +          if (orgX <= ItemInfo.Rect.right)
 +          {
 +              break;                          /* Too far right already */
 +          }
 +          ItemInfo.Rect.left += orgX - ItemInfo.Rect.right;
 +          ItemInfo.Rect.right = orgX;
 +          orgX = ItemInfo.Rect.left;
 +          MenuSetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo);
 +          if (helpPos + 1 <= i &&
 +              ! MenuGetRosMenuItemInfo(MenuInfo->Self, i - 1, &ItemInfo))
 +            {
 +                MenuCleanupRosMenuItemInfo(&ItemInfo);
 +                return;
 +            }
 +        }
 +    }
 +
 +    MenuCleanupRosMenuItemInfo(&ItemInfo);
 +}
 +
 +/***********************************************************************
 + *           MenuDrawMenuItem
 + *
 + * Draw a single menu item.
 + */
 +static void FASTCALL MenuDrawMenuItem(HWND hWnd, PROSMENUINFO MenuInfo, HWND WndOwner, HDC hdc,
 +                 PROSMENUITEMINFO lpitem, UINT Height, BOOL menuBar, UINT odaction)
 +{
 +    RECT rect;
 +    PWCHAR Text;
 +    BOOL flat_menu = FALSE;
 +    int bkgnd;
 +    PWND Wnd = ValidateHwnd(hWnd);
 +
 +    if (!Wnd)
 +      return;
 +
 +    if (lpitem->fType & MF_SYSMENU)
 +    {
 +        if ( (Wnd->style & WS_MINIMIZE))
 +        {
 +          UserGetInsideRectNC(Wnd, &rect);
 +          UserDrawSysMenuButton(hWnd, hdc, &rect,
 +                                lpitem->fState & (MF_HILITE | MF_MOUSESELECT));
 +          }
 +        return;
 +    }
 +
 +    SystemParametersInfoW (SPI_GETFLATMENU, 0, &flat_menu, 0);
 +    bkgnd = (menuBar && flat_menu) ? COLOR_MENUBAR : COLOR_MENU;
 +
 +    /* Setup colors */
 +
 +    if (lpitem->fState & MF_HILITE)
 +    {
 +        if(menuBar && !flat_menu) {
 +            SetTextColor(hdc, GetSysColor(COLOR_MENUTEXT));
 +            SetBkColor(hdc, GetSysColor(COLOR_MENU));
 +        } else {
 +            if (lpitem->fState & MF_GRAYED)
 +                SetTextColor(hdc, GetSysColor(COLOR_GRAYTEXT));
 +            else
 +                SetTextColor(hdc, GetSysColor(COLOR_HIGHLIGHTTEXT));
 +            SetBkColor(hdc, GetSysColor(COLOR_HIGHLIGHT));
 +        }
 +    }
 +    else
 +    {
 +        if (lpitem->fState & MF_GRAYED)
 +            SetTextColor( hdc, GetSysColor( COLOR_GRAYTEXT ) );
 +        else
 +            SetTextColor( hdc, GetSysColor( COLOR_MENUTEXT ) );
 +        SetBkColor( hdc, GetSysColor( bkgnd ) );
 +    }
 +
 +    rect = lpitem->Rect;
 +
 +    if (lpitem->fType & MF_OWNERDRAW)
 +    {
 +        /*
 +        ** Experimentation under Windows reveals that an owner-drawn
 +        ** menu is given the rectangle which includes the space it requested
 +        ** in its response to WM_MEASUREITEM _plus_ width for a checkmark
 +        ** and a popup-menu arrow.  This is the value of lpitem->rect.
 +        ** Windows will leave all drawing to the application except for
 +        ** the popup-menu arrow.  Windows always draws that itself, after
 +        ** the menu owner has finished drawing.
 +        */
 +        DRAWITEMSTRUCT dis;
 +
 +        dis.CtlType   = ODT_MENU;
 +        dis.CtlID     = 0;
 +        dis.itemID    = lpitem->wID;
 +        dis.itemData  = (DWORD)lpitem->dwItemData;
 +        dis.itemState = 0;
 +        if (lpitem->fState & MF_CHECKED) dis.itemState |= ODS_CHECKED;
 +        if (lpitem->fState & MF_GRAYED)  dis.itemState |= ODS_GRAYED | ODS_DISABLED;
 +        if (lpitem->fState & MF_HILITE)  dis.itemState |= ODS_SELECTED;
 +        dis.itemAction = odaction; /* ODA_DRAWENTIRE | ODA_SELECT | ODA_FOCUS; */
 +        dis.hwndItem   = (HWND) MenuInfo->Self;
 +        dis.hDC        = hdc;
 +        dis.rcItem     = rect;
 +        TRACE("Ownerdraw: owner=%p itemID=%d, itemState=%d, itemAction=%d, "
 +              "hwndItem=%p, hdc=%p, rcItem={%ld,%ld,%ld,%ld}\n", hWnd,
 +              dis.itemID, dis.itemState, dis.itemAction, dis.hwndItem,
 +              dis.hDC, dis.rcItem.left, dis.rcItem.top, dis.rcItem.right,
 +              dis.rcItem.bottom);
 +        SendMessageW(WndOwner, WM_DRAWITEM, 0, (LPARAM) &dis);
 +        /* Draw the popup-menu arrow */
 +        if (lpitem->fType & MF_POPUP)
 +        {
 +            RECT rectTemp;
 +            CopyRect(&rectTemp, &rect);
 +            rectTemp.left = rectTemp.right - GetSystemMetrics(SM_CXMENUCHECK);
 +            DrawFrameControl(hdc, &rectTemp, DFC_MENU, DFCS_MENUARROW);
 +        }
 +        return;
 +    }
 +
 +    if (menuBar && (lpitem->fType & MF_SEPARATOR)) return;
 +
 +    if (lpitem->fState & MF_HILITE)
 +    {
 +        if (flat_menu)
 +        {
 +            InflateRect (&rect, -1, -1);
 +            FillRect(hdc, &rect, GetSysColorBrush(COLOR_MENUHILIGHT));
 +            InflateRect (&rect, 1, 1);
 +            FrameRect(hdc, &rect, GetSysColorBrush(COLOR_HIGHLIGHT));
 +        }
 +        else
 +        {
 +            if(menuBar)
 +                DrawEdge(hdc, &rect, BDR_SUNKENOUTER, BF_RECT);
 +            else
 +                FillRect(hdc, &rect, GetSysColorBrush(COLOR_HIGHLIGHT));
 +        }
 +    }
 +    else
 +        FillRect( hdc, &rect, GetSysColorBrush(bkgnd) );
 +
 +    SetBkMode( hdc, TRANSPARENT );
 +
 +    /* vertical separator */
 +    if (!menuBar && (lpitem->fType & MF_MENUBARBREAK))
 +    {
 +        HPEN oldPen;
 +        RECT rc = rect;
 +
 +        rc.left -= 3;
 +        rc.top = 3;
 +        rc.bottom = Height - 3;
 +        if (flat_menu)
 +        {
 +            oldPen = SelectObject( hdc, GetStockObject(DC_PEN) );
 +            SetDCPenColor(hdc, GetSysColor(COLOR_BTNSHADOW));
 +            MoveToEx( hdc, rc.left, rc.top, NULL );
 +            LineTo( hdc, rc.left, rc.bottom );
 +            SelectObject( hdc, oldPen );
 +        }
 +        else
 +            DrawEdge (hdc, &rc, EDGE_ETCHED, BF_LEFT);
 +    }
 +
 +    /* horizontal separator */
 +    if (lpitem->fType & MF_SEPARATOR)
 +    {
 +        HPEN oldPen;
 +        RECT rc = rect;
 +
 +        rc.left++;
 +        rc.right--;
 +        rc.top += SEPARATOR_HEIGHT / 2;
 +        if (flat_menu)
 +        {
 +            oldPen = SelectObject( hdc, GetStockObject(DC_PEN) );
 +            SetDCPenColor( hdc, GetSysColor(COLOR_BTNSHADOW));
 +            MoveToEx( hdc, rc.left, rc.top, NULL );
 +            LineTo( hdc, rc.right, rc.top );
 +            SelectObject( hdc, oldPen );
 +        }
 +        else
 +            DrawEdge (hdc, &rc, EDGE_ETCHED, BF_TOP);
 +        return;
 +    }
 +
 +#if 0
 +    /* helper lines for debugging */
 +    /* This is a very good test tool when hacking menus! (JT) 07/16/2006 */
 +    FrameRect(hdc, &rect, GetStockObject(BLACK_BRUSH));
 +    SelectObject(hdc, GetStockObject(DC_PEN));
 +    SetDCPenColor(hdc, GetSysColor(COLOR_WINDOWFRAME));
 +    MoveToEx(hdc, rect.left, (rect.top + rect.bottom) / 2, NULL);
 +    LineTo(hdc, rect.right, (rect.top + rect.bottom) / 2);
 +#endif
 +
 +    if (!menuBar)
 +    {
 +        HBITMAP bm;
 +        INT y = rect.top + rect.bottom;
 +        RECT rc = rect;
 +        int checked = FALSE;
 +        UINT check_bitmap_width = GetSystemMetrics( SM_CXMENUCHECK );
 +        UINT check_bitmap_height = GetSystemMetrics( SM_CYMENUCHECK );
 +        /* Draw the check mark
 +         *
 +         * FIXME:
 +         * Custom checkmark bitmaps are monochrome but not always 1bpp.
 +         */
 +        if( !(MenuInfo->dwStyle & MNS_NOCHECK)) {
 +            bm = (lpitem->fState & MF_CHECKED) ? lpitem->hbmpChecked :
 +                lpitem->hbmpUnchecked;
 +            if (bm)  /* we have a custom bitmap */
 +            {
 +                HDC hdcMem = CreateCompatibleDC( hdc );
 +
 +                SelectObject( hdcMem, bm );
 +                BitBlt( hdc, rc.left, (y - check_bitmap_height) / 2,
 +                        check_bitmap_width, check_bitmap_height,
 +                        hdcMem, 0, 0, SRCCOPY );
 +                DeleteDC( hdcMem );
 +                checked = TRUE;
 +            }
 +            else if (lpitem->fState & MF_CHECKED) /* standard bitmaps */
 +            {
 +                RECT r;
 +                CopyRect(&r, &rect);
 +                r.right = r.left + GetSystemMetrics(SM_CXMENUCHECK);
 +                DrawFrameControl( hdc, &r, DFC_MENU,
 +                                 (lpitem->fType & MFT_RADIOCHECK) ?
 +                                 DFCS_MENUBULLET : DFCS_MENUCHECK);
 +                checked = TRUE;
 +            }
 +        }
 +        if ( lpitem->hbmpItem )
 +        {
 +            RECT bmpRect;
 +            CopyRect(&bmpRect, &rect);
 +            if (!(MenuInfo->dwStyle & MNS_CHECKORBMP) && !(MenuInfo->dwStyle & MNS_NOCHECK))
 +                bmpRect.left += check_bitmap_width + 2;
 +            if (!(checked && (MenuInfo->dwStyle & MNS_CHECKORBMP)))
 +            {
 +                bmpRect.right = bmpRect.left + MenuInfo->maxBmpSize.cx;
 +                MenuDrawBitmapItem(hdc, lpitem, &bmpRect, MenuInfo->Self, WndOwner, odaction, menuBar);
 +            }
 +        }
 +        /* Draw the popup-menu arrow */
 +        if (lpitem->fType & MF_POPUP)
 +        {
 +            RECT rectTemp;
 +            CopyRect(&rectTemp, &rect);
 +            rectTemp.left = rectTemp.right - GetSystemMetrics(SM_CXMENUCHECK);
 +            DrawFrameControl(hdc, &rectTemp, DFC_MENU, DFCS_MENUARROW);
 +        }
 +        rect.left += 4;
 +        if( !(MenuInfo->dwStyle & MNS_NOCHECK))
 +            rect.left += check_bitmap_width;
 +        rect.right -= check_bitmap_width;
 +    }
 +    else if( lpitem->hbmpItem)
 +    { /* Draw the bitmap */
 +        MenuDrawBitmapItem(hdc, lpitem, &rect, MenuInfo->Self, WndOwner, odaction, menuBar);
 +    }
 +
 +    /* process text if present */
 +    if (lpitem->lpstr)
 +    {
 +        register int i = 0;
 +        HFONT hfontOld = 0;
 +
 +        UINT uFormat = menuBar ? DT_CENTER | DT_VCENTER | DT_SINGLELINE
 +                       : DT_LEFT | DT_VCENTER | DT_SINGLELINE;
 +
 +        if(MenuInfo->dwStyle & MNS_CHECKORBMP)
 +             rect.left += max(0, MenuInfo->maxBmpSize.cx - GetSystemMetrics(SM_CXMENUCHECK));
 +        else
 +             rect.left += MenuInfo->maxBmpSize.cx;
 +
 +        if ( lpitem->fState & MFS_DEFAULT )
 +        {
 +            hfontOld = SelectObject(hdc, hMenuFontBold);
 +        }
 +
 +        if (menuBar) {
 +            rect.left += MENU_BAR_ITEMS_SPACE / 2;
 +            rect.right -= MENU_BAR_ITEMS_SPACE / 2;
 +        }
 +
 +        Text = (PWCHAR) lpitem->dwTypeData;
 +        if(Text)
 +        {
 +            for (i = 0; L'\0' != Text[i]; i++)
 +                if (Text[i] == L'\t' || Text[i] == L'\b')
 +                    break;
 +        }
 +
 +        if(lpitem->fState & MF_GRAYED)
 +        {
 +            if (!(lpitem->fState & MF_HILITE) )
 +            {
 +                ++rect.left; ++rect.top; ++rect.right; ++rect.bottom;
 +                SetTextColor(hdc, RGB(0xff, 0xff, 0xff));
 +                DrawTextW( hdc, Text, i, &rect, uFormat );
 +                --rect.left; --rect.top; --rect.right; --rect.bottom;
 +              }
 +            SetTextColor(hdc, RGB(0x80, 0x80, 0x80));
 +        }
 +
 +        DrawTextW( hdc, Text, i, &rect, uFormat);
 +
 +        /* paint the shortcut text */
 +        if (!menuBar && L'\0' != Text[i])  /* There's a tab or flush-right char */
 +        {
 +            if (L'\t' == Text[i])
 +            {
 +                rect.left = lpitem->dxTab;
 +                uFormat = DT_LEFT | DT_VCENTER | DT_SINGLELINE;
 +            }
 +            else
 +            {
 +                rect.right = lpitem->dxTab;
 +                uFormat = DT_RIGHT | DT_VCENTER | DT_SINGLELINE;
 +            }
 +
 +            if (lpitem->fState & MF_GRAYED)
 +            {
 +                if (!(lpitem->fState & MF_HILITE) )
 +                {
 +                    ++rect.left; ++rect.top; ++rect.right; ++rect.bottom;
 +                    SetTextColor(hdc, RGB(0xff, 0xff, 0xff));
 +                    DrawTextW( hdc, Text + i + 1, -1, &rect, uFormat);
 +                    --rect.left; --rect.top; --rect.right; --rect.bottom;
 +                }
 +                SetTextColor(hdc, RGB(0x80, 0x80, 0x80));
 +              }
 +          DrawTextW( hdc, Text + i + 1, -1, &rect, uFormat );
 +        }
 +
 +        if (hfontOld)
 +          SelectObject (hdc, hfontOld);
 +    }
 +}
 +
 +/***********************************************************************
 + *           MenuDrawPopupMenu
 + *
 + * Paint a popup menu.
 + */
 +static void FASTCALL MenuDrawPopupMenu(HWND hwnd, HDC hdc, HMENU hmenu )
 +{
 +    HBRUSH hPrevBrush = 0;
 +    RECT rect;
 +
 +    TRACE("wnd=%p dc=%p menu=%p\n", hwnd, hdc, hmenu);
 +
 +    GetClientRect( hwnd, &rect );
 +
 +    if((hPrevBrush = SelectObject( hdc, GetSysColorBrush(COLOR_MENU) ))
 +        && (SelectObject( hdc, hMenuFont)))
 +    {
 +        HPEN hPrevPen;
 +
 +        Rectangle( hdc, rect.left, rect.top, rect.right, rect.bottom );
 +
 +        hPrevPen = SelectObject( hdc, GetStockObject( NULL_PEN ) );
 +        if ( hPrevPen )
 +        {
 +            BOOL flat_menu = FALSE;
 +            ROSMENUINFO MenuInfo;
 +            ROSMENUITEMINFO ItemInfo;
 +
 +            SystemParametersInfoW (SPI_GETFLATMENU, 0, &flat_menu, 0);
 +            if (flat_menu)
 +               FrameRect(hdc, &rect, GetSysColorBrush(COLOR_BTNSHADOW));
 +            else
 +               DrawEdge (hdc, &rect, EDGE_RAISED, BF_RECT);
 +
 +            /* draw menu items */
 +            if (MenuGetRosMenuInfo(&MenuInfo, hmenu) && MenuInfo.MenuItemCount)
 +            {
 +                UINT u;
 +
 +                              MenuInitRosMenuItemInfo(&ItemInfo);
 +
 +                for (u = 0; u < MenuInfo.MenuItemCount; u++)
 +                {
 +                    if (MenuGetRosMenuItemInfo(MenuInfo.Self, u, &ItemInfo))
 +                    {
 +                        MenuDrawMenuItem(hwnd, &MenuInfo, MenuInfo.WndOwner, hdc, &ItemInfo,
 +                        MenuInfo.Height, FALSE, ODA_DRAWENTIRE);
 +                    }
 +                }
 +
 +                MenuCleanupRosMenuItemInfo(&ItemInfo);
 +            }
 +         } else
 +         {
 +             SelectObject( hdc, hPrevBrush );
 +         }
 +    }
 +}
 +
 +/***********************************************************************
 + *           MenuDrawMenuBar
 + *
 + * Paint a menu bar. Returns the height of the menu bar.
 + * called from [windows/nonclient.c]
 + */
 +UINT MenuDrawMenuBar( HDC hDC, LPRECT lprect, HWND hwnd,
 +                         BOOL suppress_draw)
 +{
 +    ROSMENUINFO lppop;
 +    HFONT hfontOld = 0;
 +    HMENU hMenu = GetMenu(hwnd);
 +
 +    if (! MenuGetRosMenuInfo(&lppop, hMenu) || lprect == NULL)
 +    {
 +        return GetSystemMetrics(SM_CYMENU);
 +    }
 +
 +    if (suppress_draw)
 +    {
 +        hfontOld = SelectObject(hDC, hMenuFont);
 +
 +        MenuMenuBarCalcSize(hDC, lprect, &lppop, hwnd);
 +
 +        lprect->bottom = lprect->top + lppop.Height;
 +
 +        if (hfontOld) SelectObject( hDC, hfontOld);
 +        return lppop.Height;
 +    }
 +      else
 +        return DrawMenuBarTemp(hwnd, hDC, lprect, hMenu, NULL);
 +}
 +
 +/***********************************************************************
 + *           MenuShowPopup
 + *
 + * Display a popup menu.
 + */
 +static BOOL FASTCALL MenuShowPopup(HWND hwndOwner, HMENU hmenu, UINT id, UINT flags,
 +                              INT x, INT y, INT xanchor, INT yanchor )
 +{
 +    ROSMENUINFO MenuInfo;
 +    ROSMENUITEMINFO ItemInfo;
 +    UINT width, height;
 +    POINT pt;
 +    HMONITOR monitor;
 +    MONITORINFO info;
 +
 +    TRACE("owner=%p hmenu=%p id=0x%04x x=0x%04x y=0x%04x xa=0x%04x ya=0x%04x\n",
 +          hwndOwner, hmenu, id, x, y, xanchor, yanchor);
 +
 +    if (! MenuGetRosMenuInfo(&MenuInfo, hmenu)) return FALSE;
 +    if (MenuInfo.FocusedItem != NO_SELECTED_ITEM)
 +    {
 +        MenuInitRosMenuItemInfo(&ItemInfo);
 +        if (MenuGetRosMenuItemInfo(MenuInfo.Self, MenuInfo.FocusedItem, &ItemInfo))
 +        {
 +            ItemInfo.fMask |= MIIM_STATE;
 +            ItemInfo.fState &= ~(MF_HILITE|MF_MOUSESELECT);
 +            MenuSetRosMenuItemInfo(MenuInfo.Self, MenuInfo.FocusedItem, &ItemInfo);
 +        }
 +        MenuCleanupRosMenuItemInfo(&ItemInfo);
 +        MenuInfo.FocusedItem = NO_SELECTED_ITEM;
 +    }
 +
++    /* ReactOS Check */
++    if (!ValidateHwnd(hwndOwner))
++    {  // This window maybe already DEAD!!!
++       return FALSE;
++    }
 +    /* store the owner for DrawItem */
 +    MenuInfo.WndOwner = hwndOwner;
 +    MenuSetRosMenuInfo(&MenuInfo);
 +
 +    MenuPopupMenuCalcSize(&MenuInfo, hwndOwner);
 +
 +    /* adjust popup menu pos so that it fits within the desktop */
 +
 +    width = MenuInfo.Width + GetSystemMetrics(SM_CXBORDER);
 +    height = MenuInfo.Height + GetSystemMetrics(SM_CYBORDER);
 +
 +    /* FIXME: should use item rect */
 +    pt.x = x;
 +    pt.y = y;
 +    monitor = MonitorFromPoint( pt, MONITOR_DEFAULTTONEAREST );
 +    info.cbSize = sizeof(info);
 +    GetMonitorInfoW( monitor, &info );
 +
 +    if( flags & TPM_RIGHTALIGN ) x -= width;
 +    if( flags & TPM_CENTERALIGN ) x -= width / 2;
 +
 +    if( flags & TPM_BOTTOMALIGN ) y -= height;
 +    if( flags & TPM_VCENTERALIGN ) y -= height / 2;
 +
 +    if( x + width > info.rcMonitor.right)
 +    {
 +        if( xanchor && x >= width - xanchor )
 +            x -= width - xanchor;
 +
 +        if( x + width > info.rcMonitor.right)
 +            x = info.rcMonitor.right - width;
 +    }
 +    if( x < info.rcMonitor.left ) x = info.rcMonitor.left;
 +
 +    if( y + height > info.rcMonitor.bottom)
 +    {
 +        if( yanchor && y >= height + yanchor )
 +            y -= height + yanchor;
 +
 +        if( y + height > info.rcMonitor.bottom)
 +            y = info.rcMonitor.bottom - height;
 +    }
 +    if( y < info.rcMonitor.top ) y = info.rcMonitor.top;
 +
 +    /* NOTE: In Windows, top menu popup is not owned. */
 +    MenuInfo.Wnd = CreateWindowExW( 0, WC_MENU, NULL,
 +                                  WS_POPUP, x, y, width, height,
 +                                  hwndOwner, 0, (HINSTANCE) GetWindowLongPtrW(hwndOwner, GWLP_HINSTANCE),
 +                                 (LPVOID) MenuInfo.Self);
 +    if ( !MenuInfo.Wnd || ! MenuSetRosMenuInfo(&MenuInfo)) return FALSE;
 +    if (!top_popup) {
 +        top_popup = MenuInfo.Wnd;
 +        top_popup_hmenu = hmenu;
 +    }
 +
 +    IntNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPSTART, MenuInfo.Wnd, OBJID_CLIENT, CHILDID_SELF, 0);
 +
 +    /* Display the window */
 +
 +    SetWindowPos( MenuInfo.Wnd, HWND_TOPMOST, 0, 0, 0, 0,
 +                  SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | SWP_NOACTIVATE);
 +    UpdateWindow( MenuInfo.Wnd );
 +    return TRUE;
 +}
 +
 +
 +/***********************************************************************
 + *           MenuSelectItem
 + */
 +static void FASTCALL MenuSelectItem(HWND hwndOwner, PROSMENUINFO hmenu, UINT wIndex,
 +                                    BOOL sendMenuSelect, HMENU topmenu)
 +{
 +    ROSMENUITEMINFO ItemInfo;
 +    ROSMENUINFO TopMenuInfo;
 +    HDC hdc;
 +
 +    TRACE("owner=%p menu=%p index=0x%04x select=0x%04x\n", hwndOwner, hmenu, wIndex, sendMenuSelect);
 +
 +     if (!hmenu || !hmenu->MenuItemCount || !hmenu->Wnd) return;
 +    if (hmenu->FocusedItem == wIndex) return;
 +    if (hmenu->Flags & MF_POPUP) hdc = GetDC(hmenu->Wnd);
 +    else hdc = GetDCEx(hmenu->Wnd, 0, DCX_CACHE | DCX_WINDOW);
 +    if (!top_popup) {
 +        top_popup = hmenu->Wnd;
 +        top_popup_hmenu = hmenu->Self;
 +    }
 +
 +    SelectObject( hdc, hMenuFont );
 +
 +    MenuInitRosMenuItemInfo(&ItemInfo);
 +
 +     /* Clear previous highlighted item */
 +    if (hmenu->FocusedItem != NO_SELECTED_ITEM)
 +    {
 +        if (MenuGetRosMenuItemInfo(hmenu->Self, hmenu->FocusedItem, &ItemInfo))
 +        {
 +            ItemInfo.fMask |= MIIM_STATE;
 +            ItemInfo.fState &= ~(MF_HILITE|MF_MOUSESELECT);
 +            MenuSetRosMenuItemInfo(hmenu->Self, hmenu->FocusedItem, &ItemInfo);
 +        }
 +        MenuDrawMenuItem(hmenu->Wnd, hmenu, hwndOwner, hdc, &ItemInfo,
 +                       hmenu->Height, ! (hmenu->Flags & MF_POPUP),
 +                       ODA_SELECT);
 +    }
 +
 +    /* Highlight new item (if any) */
 +    hmenu->FocusedItem = wIndex;
 +    MenuSetRosMenuInfo(hmenu);
 +    if (hmenu->FocusedItem != NO_SELECTED_ITEM)
 +    {
 +        if (MenuGetRosMenuItemInfo(hmenu->Self, hmenu->FocusedItem, &ItemInfo))
 +        {
 +            if (!(ItemInfo.fType & MF_SEPARATOR))
 +            {
 +                ItemInfo.fMask |= MIIM_STATE;
 +                ItemInfo.fState |= MF_HILITE;
 +                MenuSetRosMenuItemInfo(hmenu->Self, hmenu->FocusedItem, &ItemInfo);
 +                MenuDrawMenuItem(hmenu->Wnd, hmenu, hwndOwner, hdc,
 +                               &ItemInfo, hmenu->Height, ! (hmenu->Flags & MF_POPUP),
 +                               ODA_SELECT);
 +            }
 +            if (sendMenuSelect)
 +            {
 +                SendMessageW(hwndOwner, WM_MENUSELECT,
 +                           MAKELONG(ItemInfo.fType & MF_POPUP ? wIndex : ItemInfo.wID,
 +                                    ItemInfo.fType | ItemInfo.fState | MF_MOUSESELECT |
 +                                    (hmenu->Flags & MF_SYSMENU)), (LPARAM) hmenu->Self);
 +            }
 +        }
 +    }
 +    else if (sendMenuSelect) {
 +        if(topmenu) {
 +            int pos;
 +            pos = MenuFindSubMenu(&topmenu, hmenu->Self);
 +            if (pos != NO_SELECTED_ITEM)
 +            {
 +                if (MenuGetRosMenuInfo(&TopMenuInfo, topmenu)
 +                    && MenuGetRosMenuItemInfo(topmenu, pos, &ItemInfo))
 +                {
 +                    SendMessageW(hwndOwner, WM_MENUSELECT,
 +                               MAKELONG(Pos, ItemInfo.fType | ItemInfo.fState
 +                                             | MF_MOUSESELECT
 +                                             | (TopMenuInfo.Flags & MF_SYSMENU)),
 +                               (LPARAM) topmenu);
 +                }
 +            }
 +        }
 +    }
 +    MenuCleanupRosMenuItemInfo(&ItemInfo);
 +    ReleaseDC(hmenu->Wnd, hdc);
 +}
 +
 +/***********************************************************************
 + *           MenuMoveSelection
 + *
 + * Moves currently selected item according to the Offset parameter.
 + * If there is no selection then it should select the last item if
 + * Offset is ITEM_PREV or the first item if Offset is ITEM_NEXT.
 + */
 +static void FASTCALL
 +MenuMoveSelection(HWND WndOwner, PROSMENUINFO MenuInfo, INT Offset)
 +{
 +  INT i;
 +  ROSMENUITEMINFO ItemInfo;
 +  INT OrigPos;
 +
 +  TRACE("hwnd=%x menu=%x off=0x%04x\n", WndOwner, MenuInfo, Offset);
 +
 +  /* Prevent looping */
 +  if (0 == MenuInfo->MenuItemCount || 0 == Offset)
 +    return;
 +  else if (Offset < -1)
 +    Offset = -1;
 +  else if (Offset > 1)
 +    Offset = 1;
 +
 +  MenuInitRosMenuItemInfo(&ItemInfo);
 +
 +  OrigPos = MenuInfo->FocusedItem;
 +  if (OrigPos == NO_SELECTED_ITEM) /* NO_SELECTED_ITEM is not -1 ! */
 +    {
 +       OrigPos = 0;
 +       i = -1;
 +    }
 +  else
 +    {
 +      i = MenuInfo->FocusedItem;
 +    }
 +
 +  do
 +    {
 +      /* Step */
 +      i += Offset;
 +      /* Clip and wrap around */
 +      if (i < 0)
 +        {
 +          i = MenuInfo->MenuItemCount - 1;
 +        }
 +      else if (i >= MenuInfo->MenuItemCount)
 +        {
 +          i = 0;
 +        }
 +      /* If this is a good candidate; */
 +      if (MenuGetRosMenuItemInfo(MenuInfo->Self, i, &ItemInfo) &&
 +          0 == (ItemInfo.fType & MF_SEPARATOR))
 +        {
 +          MenuSelectItem(WndOwner, MenuInfo, i, TRUE, NULL);
 +          MenuCleanupRosMenuItemInfo(&ItemInfo);
 +          return;
 +        }
 +    } while (i != OrigPos);
 +
 +  /* Not found */
 +  MenuCleanupRosMenuItemInfo(&ItemInfo);
 +}
 +
 +//
 +// This breaks some test results. Should handle A2U if called!
 +//
 +LRESULT WINAPI PopupMenuWndProcA(HWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam)
 +{
 +  TRACE("YES! hwnd=%x msg=0x%04x wp=0x%04lx lp=0x%08lx\n", Wnd, Message, wParam, lParam);
 +#ifdef __REACTOS__
 +  PWND pWnd;
 +
 +  pWnd = ValidateHwnd(Wnd);
 +  if (pWnd)
 +  {
 +     if (!pWnd->fnid)
 +     {
 +        NtUserSetWindowFNID(Wnd, FNID_MENU);
 +     }
 +  }    
 +#endif    
 +
 +  switch(Message)
 +    {
 +    case WM_CREATE:
 +      {
 +        CREATESTRUCTA *cs = (CREATESTRUCTA *) lParam;
 +        SetWindowLongPtrA(Wnd, 0, (LONG_PTR)cs->lpCreateParams);
 +        return 0;
 +      }
 +
 +    case WM_MOUSEACTIVATE:  /* We don't want to be activated */
 +      return MA_NOACTIVATE;
 +
 +    case WM_PAINT:
 +      {
 +        PAINTSTRUCT ps;
 +        BeginPaint(Wnd, &ps);
 +        MenuDrawPopupMenu(Wnd, ps.hdc, (HMENU)GetWindowLongPtrA(Wnd, 0));
 +        EndPaint(Wnd, &ps);
 +        return 0;
 +      }
 +
 +    case WM_PRINTCLIENT:
 +      {
 +        MenuDrawPopupMenu( Wnd, (HDC)wParam,
 +                                (HMENU)GetWindowLongPtrW( Wnd, 0 ) );
 +        return 0;
 +      }
 +
 +    case WM_ERASEBKGND:
 +      return 1;
 +
 +    case WM_DESTROY:
 +      /* zero out global pointer in case resident popup window was destroyed. */
 +      if (Wnd == top_popup)
 +        {
 +          top_popup = NULL;
 +          top_popup_hmenu = NULL;
 +        }
 +#ifdef __REACTOS__
 +      NtUserSetWindowFNID(Wnd, FNID_DESTROY);
 +#endif
 +      break;
 +
 +    case WM_SHOWWINDOW:
 +      if (0 != wParam)
 +        {
 +          if (0 == GetWindowLongPtrA(Wnd, 0))
 +            {
 +              OutputDebugStringA("no menu to display\n");
 +            }
 +        }
 +      else
 +        {
 +          SetWindowLongPtrA(Wnd, 0, 0);
 +        }
 +      break;
 +
 +    case MM_SETMENUHANDLE:
 +      SetWindowLongPtrA(Wnd, 0, wParam);
 +      break;
 +
 +    case MM_GETMENUHANDLE:
 +    case MN_GETHMENU:
 +      return GetWindowLongPtrA(Wnd, 0);
 +
 +    default:
 +      return DefWindowProcA(Wnd, Message, wParam, lParam);
 +    }
 +  return 0;
 +}
 +
 +LRESULT WINAPI
 +PopupMenuWndProcW(HWND Wnd, UINT Message, WPARAM wParam, LPARAM lParam)
 +{
 +  TRACE("hwnd=%x msg=0x%04x wp=0x%04lx lp=0x%08lx\n", Wnd, Message, wParam, lParam);
 +#ifdef __REACTOS__ // Do this now, remove after Server side is fixed.
 +  PWND pWnd;
 +
 +  pWnd = ValidateHwnd(Wnd);
 +  if (pWnd)
 +  {
 +     if (!pWnd->fnid)
 +     {
 +        NtUserSetWindowFNID(Wnd, FNID_MENU);
 +     }
 +  }    
 +#endif    
 +
 +  switch(Message)
 +    {
 +    case WM_CREATE:
 +      {
 +        CREATESTRUCTW *cs = (CREATESTRUCTW *) lParam;
 +        SetWindowLongPtrW(Wnd, 0, (LONG_PTR)cs->lpCreateParams);
 +        return 0;
 +      }
 +
 +    case WM_MOUSEACTIVATE:  /* We don't want to be activated */
 +      return MA_NOACTIVATE;
 +
 +    case WM_PAINT:
 +      {
 +        PAINTSTRUCT ps;
 +        BeginPaint(Wnd, &ps);
 +        MenuDrawPopupMenu(Wnd, ps.hdc, (HMENU)GetWindowLongPtrW(Wnd, 0));
 +        EndPaint(Wnd, &ps);
 +        return 0;
 +      }
 +
 +    case WM_PRINTCLIENT:
 +      {
 +         MenuDrawPopupMenu( Wnd, (HDC)wParam,
 +                                (HMENU)GetWindowLongPtrW( Wnd, 0 ) );
 +         return 0;
 +      }
 +
 +    case WM_ERASEBKGND:
 +      return 1;
 +
 +    case WM_DESTROY:
 +      /* zero out global pointer in case resident popup window was destroyed. */
 +      if (Wnd == top_popup)
 +        {
 +          top_popup = NULL;
 +          top_popup_hmenu = NULL;
 +        }
 +#ifdef __REACTOS__
 +      NtUserSetWindowFNID(Wnd, FNID_DESTROY);
 +#endif
 +      break;
 +
 +    case WM_SHOWWINDOW:
 +      if (0 != wParam)
 +        {
 +          if (0 == GetWindowLongPtrW(Wnd, 0))
 +            {
 +              OutputDebugStringA("no menu to display\n");
 +            }
 +        }
 +      else
 +        {
 +          SetWindowLongPtrW(Wnd, 0, 0);
 +        }
 +      break;
 +
 +    case MM_SETMENUHANDLE:
 +      SetWindowLongPtrW(Wnd, 0, wParam);
 +      break;
 +
 +    case MM_GETMENUHANDLE:
 +    case MN_GETHMENU:
 +      return GetWindowLongPtrW(Wnd, 0);
 +
 +    default:
 +      return DefWindowProcW(Wnd, Message, wParam, lParam);
 +    }
 +
 +  return 0;
 +}
 +
 +/**********************************************************************
 + *         MENU_ParseResource
 + *
 + * Parse a standard menu resource and add items to the menu.
 + * Return a pointer to the end of the resource.
 + *
 + * NOTE: flags is equivalent to the mtOption field
 + */
 +static LPCSTR MENU_ParseResource( LPCSTR res, HMENU hMenu, BOOL unicode )
 +{
 +    WORD flags, id = 0;
 +    HMENU hSubMenu;
 +    LPCSTR str;
 +    BOOL end = FALSE;
 +
 +    do
 +    {
 +        flags = GET_WORD(res);
 +
 +        /* remove MF_END flag before passing it to AppendMenu()! */
 +        end = (flags & MF_END);
 +        if(end) flags ^= MF_END;
 +
 +        res += sizeof(WORD);
 +        if(!(flags & MF_POPUP))
 +        {
 +            id = GET_WORD(res);
 +            res += sizeof(WORD);
 +        }
 +        str = res;
 +        if(!unicode)
 +            res += strlen(str) + 1;
 +        else
 +            res += (strlenW((LPCWSTR)str) + 1) * sizeof(WCHAR);
 +        if (flags & MF_POPUP)
 +        {
 +            hSubMenu = CreatePopupMenu();
 +            if(!hSubMenu) return NULL;
 +            if(!(res = MENU_ParseResource(res, hSubMenu, unicode)))
 +                return NULL;
 +            if(!unicode)
 +                AppendMenuA(hMenu, flags, (UINT)hSubMenu, str);
 +            else
 +                AppendMenuW(hMenu, flags, (UINT)hSubMenu, (LPCWSTR)str);
 +        }
 +        else  /* Not a popup */
 +        {
 +            if(!unicode)
 +            {
 +                if (*str == 0)
 +                    flags = MF_SEPARATOR;
 +            }
 +            else
 +            {
 +                if (*(LPCWSTR)str == 0)
 +                    flags = MF_SEPARATOR;
 +            }
 +
 +            if (flags & MF_SEPARATOR)
 +            {
 +                if (!(flags & (MF_GRAYED | MF_DISABLED)))
 +                    flags |= MF_GRAYED | MF_DISABLED;
 +            }
 +
 +            if(!unicode)
 +                AppendMenuA(hMenu, flags, id, *str ? str : NULL);
 +            else
 +                AppendMenuW(hMenu, flags, id,
 +                    *(LPCWSTR)str ? (LPCWSTR)str : NULL);
 +        }
 +    } while(!end);
 +    return res;
 +}
 +
 +
 +/**********************************************************************
 + *         MENUEX_ParseResource
 + *
 + * Parse an extended menu resource and add items to the menu.
 + * Return a pointer to the end of the resource.
 + */
 +static LPCSTR MENUEX_ParseResource( LPCSTR res, HMENU hMenu)
 +{
 +    WORD resinfo;
 +    do {
 +        MENUITEMINFOW mii;
 +
 +        mii.cbSize = sizeof(mii);
 +        mii.fMask = MIIM_STATE | MIIM_ID | MIIM_FTYPE;
 +        mii.fType = GET_DWORD(res);
 +        res += sizeof(DWORD);
 +        mii.fState = GET_DWORD(res);
 +        res += sizeof(DWORD);
 +        mii.wID = GET_DWORD(res);
 +        res += sizeof(DWORD);
 +        resinfo = GET_WORD(res);
 +        res += sizeof(WORD);
 +        /* Align the text on a word boundary.  */
 +        res += (~((UINT_PTR)res - 1)) & 1;
 +        mii.dwTypeData = (LPWSTR) res;
 +        res += (1 + strlenW(mii.dwTypeData)) * sizeof(WCHAR);
 +        /* Align the following fields on a dword boundary.  */
 +        res += (~((UINT_PTR)res - 1)) & 3;
 +
 +        TRACE("Menu item: [%08x,%08x,%04x,%04x,%S]\n",
 +              mii.fType, mii.fState, mii.wID, resinfo, mii.dwTypeData);
 +
 +              if (resinfo & 1) { /* Pop-up? */
 +            /* DWORD helpid = GET_DWORD(res); FIXME: use this.  */
 +            res += sizeof(DWORD);
 +            mii.hSubMenu = CreatePopupMenu();
 +            if (!mii.hSubMenu)
 +                return NULL;
 +            if (!(res = MENUEX_ParseResource(res, mii.hSubMenu))) {
 +                DestroyMenu(mii.hSubMenu);
 +                return NULL;
 +            }
 +            mii.fMask |= MIIM_SUBMENU;
 +            mii.fType |= MF_POPUP;
 +            mii.wID = (UINT) mii.hSubMenu;
 +        }
 +        else if(!*mii.dwTypeData && !(mii.fType & MF_SEPARATOR))
 +        {
 +            mii.fType |= MF_SEPARATOR;
 +        }
 +        InsertMenuItemW(hMenu, -1, MF_BYPOSITION, &mii);
 +    } while (!(resinfo & MF_END));
 +    return res;
 +}
 +
 +NTSTATUS WINAPI
 +User32LoadSysMenuTemplateForKernel(PVOID Arguments, ULONG ArgumentLength)
 +{
 +  HMENU hmenu = LoadMenuW(User32Instance, L"SYSMENU");
 +  LRESULT Result = (LRESULT)hmenu;
 +  MENUINFO menuinfo = {0};
 +  MENUITEMINFOW info = {0};
 +
 +  // removing space for checkboxes from menu
 +  menuinfo.cbSize = sizeof(menuinfo);
 +  menuinfo.fMask = MIM_STYLE;
 +  GetMenuInfo(hmenu, &menuinfo);
 +  menuinfo.dwStyle |= MNS_NOCHECK;
 +  SetMenuInfo(hmenu, &menuinfo);
 +
 +  // adding bitmaps to menu items
 +  info.cbSize = sizeof(info);
 +  info.fMask |= MIIM_BITMAP;
 +  info.hbmpItem = HBMMENU_POPUP_MINIMIZE;
 +  SetMenuItemInfoW(hmenu, SC_MINIMIZE, FALSE, &info);
 +  info.hbmpItem = HBMMENU_POPUP_RESTORE;
 +  SetMenuItemInfoW(hmenu, SC_RESTORE, FALSE, &info);
 +  info.hbmpItem = HBMMENU_POPUP_MAXIMIZE;
 +  SetMenuItemInfoW(hmenu, SC_MAXIMIZE, FALSE, &info);
 +  info.hbmpItem = HBMMENU_POPUP_CLOSE;
 +  SetMenuItemInfoW(hmenu, SC_CLOSE, FALSE, &info);
 +
 +  return(ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS));
 +}
 +
 +
 +BOOL
 +MenuInit(VOID)
 +{
 +  NONCLIENTMETRICSW ncm;
 +
 +  /* get the menu font */
 +  if(!hMenuFont || !hMenuFontBold)
 +  {
 +    ncm.cbSize = sizeof(ncm);
 +    if(!SystemParametersInfoW(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0))
 +    {
 +      DbgPrint("MenuInit(): SystemParametersInfoW(SPI_GETNONCLIENTMETRICS) failed!\n");
 +      return FALSE;
 +    }
 +
 +    hMenuFont = CreateFontIndirectW(&ncm.lfMenuFont);
 +    if(hMenuFont == NULL)
 +    {
 +      DbgPrint("MenuInit(): CreateFontIndirectW(hMenuFont) failed!\n");
 +      return FALSE;
 +    }
 +
 +    ncm.lfMenuFont.lfWeight = max(ncm.lfMenuFont.lfWeight + 300, 1000);
 +    hMenuFontBold = CreateFontIndirectW(&ncm.lfMenuFont);
 +    if(hMenuFontBold == NULL)
 +    {
 +      DbgPrint("MenuInit(): CreateFontIndirectW(hMenuFontBold) failed!\n");
 +      DeleteObject(hMenuFont);
 +      hMenuFont = NULL;
 +      return FALSE;
 +    }
 +  }
 +
 +  return TRUE;
 +}
 +
 +VOID
 +MenuCleanup(VOID)
 +{
 +  if (hMenuFont)
 +  {
 +    DeleteObject(hMenuFont);
 +    hMenuFont = NULL;
 +  }
 +
 +  if (hMenuFontBold)
 +  {
 +    DeleteObject(hMenuFontBold);
 +    hMenuFontBold = NULL;
 +  }
 +}
 +
 +/***********************************************************************
 + *           DrawMenuBarTemp   (USER32.@)
 + *
 + * UNDOCUMENTED !!
 + *
 + * called by W98SE desk.cpl Control Panel Applet
 + *
 + * Not 100% sure about the param names, but close.
 + *
 + * @implemented
 + */
 +DWORD WINAPI
 +DrawMenuBarTemp(HWND Wnd, HDC DC, LPRECT Rect, HMENU Menu, HFONT Font)
 +{
 +  ROSMENUINFO MenuInfo;
 +  ROSMENUITEMINFO ItemInfo;
 +  UINT i;
 +  HFONT FontOld = NULL;
 +  BOOL flat_menu = FALSE;
 +
 +  SystemParametersInfoW (SPI_GETFLATMENU, 0, &flat_menu, 0);
 +
 +  if (NULL == Menu)
 +    {
 +      Menu = GetMenu(Wnd);
 +    }
 +
 +  if (NULL == Font)
 +    {
 +      Font = hMenuFont;
 +    }
 +
 +  if (NULL == Rect || ! MenuGetRosMenuInfo(&MenuInfo, Menu))
 +    {
 +      return GetSystemMetrics(SM_CYMENU);
 +    }
 +
 +  TRACE("(%x, %x, %p, %x, %x)\n", Wnd, DC, Rect, Menu, Font);
 +
 +  FontOld = SelectObject(DC, Font);
 +
 +  if (0 == MenuInfo.Height)
 +    {
 +      MenuMenuBarCalcSize(DC, Rect, &MenuInfo, Wnd);
 +    }
 +
 +  Rect->bottom = Rect->top + MenuInfo.Height;
 +
 +  FillRect(DC, Rect, GetSysColorBrush(flat_menu ? COLOR_MENUBAR : COLOR_MENU));
 +
 +  SelectObject(DC, GetStockObject(DC_PEN));
 +  SetDCPenColor(DC, GetSysColor(COLOR_3DFACE));
 +  MoveToEx(DC, Rect->left, Rect->bottom - 1, NULL);
 +  LineTo(DC, Rect->right, Rect->bottom - 1);
 +
 +  if (0 == MenuInfo.MenuItemCount)
 +    {
 +      SelectObject(DC, FontOld);
 +      return GetSystemMetrics(SM_CYMENU);
 +    }
 +
 +  MenuInitRosMenuItemInfo(&ItemInfo);
 +  for (i = 0; i < MenuInfo.MenuItemCount; i++)
 +    {
 +      if (MenuGetRosMenuItemInfo(MenuInfo.Self, i, &ItemInfo))
 +        {
 +          MenuDrawMenuItem(Wnd, &MenuInfo, Wnd, DC, &ItemInfo,
 +                           MenuInfo.Height, TRUE, ODA_DRAWENTIRE);
 +        }
 +    }
 +  MenuCleanupRosMenuItemInfo(&ItemInfo);
 +
 +  SelectObject(DC, FontOld);
 +
 +  return MenuInfo.Height;
 +}
 +
 +/***********************************************************************
 + *           MenuShowSubPopup
 + *
 + * Display the sub-menu of the selected item of this menu.
 + * Return the handle of the submenu, or menu if no submenu to display.
 + */
 +static HMENU FASTCALL
 +MenuShowSubPopup(HWND WndOwner, PROSMENUINFO MenuInfo, BOOL SelectFirst, UINT Flags)
 +{
 +  extern void FASTCALL NcGetSysPopupPos(HWND Wnd, RECT *Rect);
 +  RECT Rect;
 +  ROSMENUITEMINFO ItemInfo;
 +  ROSMENUINFO SubMenuInfo;
 +  HDC Dc;
 +  HMENU Ret;
 +
 +  TRACE("owner=%x menu=%p 0x%04x\n", WndOwner, MenuInfo, SelectFirst);
 +
 +  if (NO_SELECTED_ITEM == MenuInfo->FocusedItem)
 +    {
 +      return MenuInfo->Self;
 +    }
 +
 +  MenuInitRosMenuItemInfo(&ItemInfo);
 +  if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo))
 +    {
 +      MenuCleanupRosMenuItemInfo(&ItemInfo);
 +      return MenuInfo->Self;
 +    }
 +  if (0 == (ItemInfo.fType & MF_POPUP) || 0 != (ItemInfo.fState & (MF_GRAYED | MF_DISABLED)))
 +    {
 +      MenuCleanupRosMenuItemInfo(&ItemInfo);
 +      return MenuInfo->Self;
 +    }
 +
 +  /* message must be sent before using item,
 +     because nearly everything may be changed by the application ! */
 +
 +  /* Send WM_INITMENUPOPUP message only if TPM_NONOTIFY flag is not specified */
 +  if (0 == (Flags & TPM_NONOTIFY))
 +    {
 +      SendMessageW(WndOwner, WM_INITMENUPOPUP, (WPARAM) ItemInfo.hSubMenu,
 +                   MAKELONG(MenuInfo->FocusedItem, IS_SYSTEM_MENU(MenuInfo)));
 +    }
 +
 +  if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo))
 +    {
 +      MenuCleanupRosMenuItemInfo(&ItemInfo);
 +      return MenuInfo->Self;
 +    }
 +  Rect = ItemInfo.Rect;
 +
 +  /* correct item if modified as a reaction to WM_INITMENUPOPUP message */
 +  if (0 == (ItemInfo.fState & MF_HILITE))
 +    {
 +      if (0 != (MenuInfo->Flags & MF_POPUP))
 +        {
 +          Dc = GetDC(MenuInfo->Wnd);
 +        }
 +      else
 +        {
 +          Dc = GetDCEx(MenuInfo->Wnd, 0, DCX_CACHE | DCX_WINDOW);
 +        }
 +
 +      SelectObject(Dc, hMenuFont);
 +      ItemInfo.fMask |= MIIM_STATE;
 +      ItemInfo.fState |= MF_HILITE;
 +      MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo);
 +      MenuDrawMenuItem(MenuInfo->Wnd, MenuInfo, WndOwner, Dc, &ItemInfo, MenuInfo->Height,
 +                       ! (MenuInfo->Flags & MF_POPUP), ODA_DRAWENTIRE);
 +      ReleaseDC(MenuInfo->Wnd, Dc);
 +    }
 +
 +  if (0 == ItemInfo.Rect.top && 0 == ItemInfo.Rect.left
 +      && 0 == ItemInfo.Rect.bottom && 0 == ItemInfo.Rect.right)
 +    {
 +      ItemInfo.Rect = Rect;
 +    }
 +
 +  ItemInfo.fMask |= MIIM_STATE;
 +  ItemInfo.fState |= MF_MOUSESELECT;
 +  MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo);
 +
 +  if (IS_SYSTEM_MENU(MenuInfo))
 +    {
 +      MenuInitSysMenuPopup(ItemInfo.hSubMenu, GetWindowLongPtrW(MenuInfo->Wnd, GWL_STYLE),
 +                           GetClassLongPtrW(MenuInfo->Wnd, GCL_STYLE), HTSYSMENU);
 +
 +      NcGetSysPopupPos(MenuInfo->Wnd, &Rect);
 +      Rect.top = Rect.bottom;
 +      Rect.right = GetSystemMetrics(SM_CXSIZE);
 +      Rect.bottom = GetSystemMetrics(SM_CYSIZE);
 +    }
 +  else
 +    {
 +      GetWindowRect(MenuInfo->Wnd, &Rect);
 +      if (0 != (MenuInfo->Flags & MF_POPUP))
 +      {
 +          Rect.left += ItemInfo.Rect.right - GetSystemMetrics(SM_CXBORDER);
 +          Rect.top += ItemInfo.Rect.top - 3;
 +          Rect.right = ItemInfo.Rect.left - ItemInfo.Rect.right + GetSystemMetrics(SM_CXBORDER);
 +          Rect.bottom = ItemInfo.Rect.top - ItemInfo.Rect.bottom - 3 - 2
 +                                                    - GetSystemMetrics(SM_CYBORDER);
 +        }
 +      else
 +        {
 +          Rect.left += ItemInfo.Rect.left;
 +          Rect.top += ItemInfo.Rect.bottom;
 +          Rect.right = ItemInfo.Rect.right - ItemInfo.Rect.left;
 +          Rect.bottom = ItemInfo.Rect.bottom - ItemInfo.Rect.top;
 +        }
 +    }
 +
 +  MenuShowPopup(WndOwner, ItemInfo.hSubMenu, MenuInfo->FocusedItem, Flags,
 +                Rect.left, Rect.top, Rect.right, Rect.bottom );
 +  if (SelectFirst && MenuGetRosMenuInfo(&SubMenuInfo, ItemInfo.hSubMenu))
 +    {
 +      MenuMoveSelection(WndOwner, &SubMenuInfo, ITEM_NEXT);
 +    }
 +
 +  Ret = ItemInfo.hSubMenu;
 +  MenuCleanupRosMenuItemInfo(&ItemInfo);
 +
 +  return Ret;
 +}
 +
 +/**********************************************************************
 + *         MENU_EndMenu
 + *
 + * Calls EndMenu() if the hwnd parameter belongs to the menu owner
 + *
 + * Does the (menu stuff) of the default window handling of WM_CANCELMODE
 + */
 +void MENU_EndMenu( HWND hwnd )
 +{
 +    ROSMENUINFO MenuInfo;
 +    BOOL Ret = FALSE;
 +    if (top_popup_hmenu)
 +       Ret = MenuGetRosMenuInfo(&MenuInfo, top_popup_hmenu);
 +    if (Ret && hwnd == MenuInfo.WndOwner) EndMenu();
 +}
 +
 +/***********************************************************************
 + *           MenuHideSubPopups
 + *
 + * Hide the sub-popup menus of this menu.
 + */
 +static void FASTCALL
 +MenuHideSubPopups(HWND WndOwner, PROSMENUINFO MenuInfo,
 +                               BOOL SendMenuSelect, UINT wFlags)
 +{
 +  ROSMENUINFO SubMenuInfo;
 +  ROSMENUITEMINFO ItemInfo;
 +
 +  TRACE("owner=%x menu=%x 0x%04x\n", WndOwner, MenuInfo, SendMenuSelect);
 +
 +  if (NULL != MenuInfo && NULL != top_popup && NO_SELECTED_ITEM != MenuInfo->FocusedItem)
 +  {
 +      MenuInitRosMenuItemInfo(&ItemInfo);
 +      ItemInfo.fMask |= MIIM_FTYPE | MIIM_STATE;
 +      if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo)
 +          || 0 == (ItemInfo.fType & MF_POPUP)
 +          || 0 == (ItemInfo.fState & MF_MOUSESELECT))
 +      {
 +          MenuCleanupRosMenuItemInfo(&ItemInfo);
 +          return;
 +      }
 +      ItemInfo.fState &= ~MF_MOUSESELECT;
 +      ItemInfo.fMask |= MIIM_STATE;
 +      MenuSetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo);
 +      if (MenuGetRosMenuInfo(&SubMenuInfo, ItemInfo.hSubMenu))
 +      {
 +          MenuHideSubPopups(WndOwner, &SubMenuInfo, FALSE, wFlags);
 +          MenuSelectItem(WndOwner, &SubMenuInfo, NO_SELECTED_ITEM, SendMenuSelect, NULL);
 +          DestroyWindow(SubMenuInfo.Wnd);
 +          SubMenuInfo.Wnd = NULL;
 +          MenuSetRosMenuInfo(&SubMenuInfo);
 +
 +          if (!(wFlags & TPM_NONOTIFY))
 +             SendMessageW( WndOwner, WM_UNINITMENUPOPUP, (WPARAM)ItemInfo.hSubMenu,
 +                                 MAKELPARAM(0, IS_SYSTEM_MENU(&SubMenuInfo)) );
 +      }
 +  }
 +}
 +
 +/***********************************************************************
 + *           MenuSwitchTracking
 + *
 + * Helper function for menu navigation routines.
 + */
 +static void FASTCALL
 +MenuSwitchTracking(MTRACKER* Mt, PROSMENUINFO PtMenuInfo, UINT Index, UINT wFlags)
 +{
 +  ROSMENUINFO TopMenuInfo;
 +
 +  TRACE("%x menu=%x 0x%04x\n", Mt, PtMenuInfo->Self, Index);
 +
 +  if (MenuGetRosMenuInfo(&TopMenuInfo, Mt->TopMenu) &&
 +      Mt->TopMenu != PtMenuInfo->Self &&
 +      0 == ((PtMenuInfo->Flags | TopMenuInfo.Flags) & MF_POPUP))
 +    {
 +      /* both are top level menus (system and menu-bar) */
 +      MenuHideSubPopups(Mt->OwnerWnd, &TopMenuInfo, FALSE, wFlags);
 +      MenuSelectItem(Mt->OwnerWnd, &TopMenuInfo, NO_SELECTED_ITEM, FALSE, NULL);
 +      Mt->TopMenu = PtMenuInfo->Self;
 +    }
 +  else
 +    {
 +      MenuHideSubPopups(Mt->OwnerWnd, PtMenuInfo, FALSE, wFlags);
 +    }
 +
 +  MenuSelectItem(Mt->OwnerWnd, PtMenuInfo, Index, TRUE, NULL);
 +}
 +
 +/***********************************************************************
 + *           MenuExecFocusedItem
 + *
 + * Execute a menu item (for instance when user pressed Enter).
 + * Return the wID of the executed item. Otherwise, -1 indicating
 + * that no menu item was executed, -2 if a popup is shown;
 + * Have to receive the flags for the TrackPopupMenu options to avoid
 + * sending unwanted message.
 + *
 + */
 +static INT FASTCALL
 +MenuExecFocusedItem(MTRACKER *Mt, PROSMENUINFO MenuInfo, UINT Flags)
 +{
 +  ROSMENUITEMINFO ItemInfo;
 +  UINT wID;
 +
 +  TRACE("%p menu=%p\n", Mt, MenuInfo);
 +
 +  if (0 == MenuInfo->MenuItemCount || NO_SELECTED_ITEM == MenuInfo->FocusedItem)
 +    {
 +      return -1;
 +    }
 +
 +  MenuInitRosMenuItemInfo(&ItemInfo);
 +  if (! MenuGetRosMenuItemInfo(MenuInfo->Self, MenuInfo->FocusedItem, &ItemInfo))
 +    {
 +      MenuCleanupRosMenuItemInfo(&ItemInfo);
 +      return -1;
 +    }
 +
 +  TRACE("%p %08x %p\n", MenuInfo, ItemInfo.wID, ItemInfo.hSubMenu);
 +
 +  if (0 == (ItemInfo.fType & MF_POPUP))
 +    {
 +      if (0 == (ItemInfo.fState & (MF_GRAYED | MF_DISABLED))
 +          && 0 == (ItemInfo.fType & MF_SEPARATOR))
 +        {
 +          /* If TPM_RETURNCMD is set you return the id, but
 +            do not send a message to the owner */
 +          if (0 == (Flags & TPM_RETURNCMD))
 +          {
 +              if (0 != (MenuInfo->Flags & MF_SYSMENU))
 +                {
 +                  PostMessageW(Mt->OwnerWnd, WM_SYSCOMMAND, ItemInfo.wID,
 +                               MAKELPARAM((SHORT) Mt->Pt.x, (SHORT) Mt->Pt.y));
 +                }
 +              else
 +                {
 +                  if (MenuInfo->dwStyle & MNS_NOTIFYBYPOS)
 +                      PostMessageW(Mt->OwnerWnd, WM_MENUCOMMAND,
 +                                                 MenuInfo->FocusedItem,
 +                                                       (LPARAM)MenuInfo->Self);
 +                  else
 +                    PostMessageW(Mt->OwnerWnd, WM_COMMAND, ItemInfo.wID, 0);
 +                }
 +            }
 +          wID = ItemInfo.wID;
 +          MenuCleanupRosMenuItemInfo(&ItemInfo);
 +        return wID;
 +        }
 +    }
 +  else
 +    {
 +      Mt->CurrentMenu = MenuShowSubPopup(Mt->OwnerWnd, MenuInfo, TRUE, Flags);
 +      return -2;
 +    }
 +
 +  return -1;
 +}
 +
 +/***********************************************************************
 + *           MenuButtonDown
 + *
 + * Return TRUE if we can go on with menu tracking.
 + */
 +static BOOL FASTCALL
 +MenuButtonDown(MTRACKER* Mt, HMENU PtMenu, UINT Flags)
 +{
 +  int Index;
 +  ROSMENUINFO MenuInfo;
 +  ROSMENUITEMINFO Item;
 +
 +  TRACE("%x PtMenu=%p\n", Mt, PtMenu);
 +
 +  if (NULL != PtMenu)
 +    {
 +      if (! MenuGetRosMenuInfo(&MenuInfo, PtMenu))
 +        {
 +          return FALSE;
 +        }
 +      if (IS_SYSTEM_MENU(&MenuInfo))
 +        {
 +          Index = 0;
 +        }
 +      else
 +        {
 +          Index = NtUserMenuItemFromPoint(Mt->OwnerWnd, PtMenu, Mt->Pt.x, Mt->Pt.y);
 +        }
 +      MenuInitRosMenuItemInfo(&Item);
 +      if (NO_SELECTED_ITEM == Index || ! MenuGetRosMenuItemInfo(PtMenu, Index, &Item))
 +        {
 +          MenuCleanupRosMenuItemInfo(&Item);
 +          return FALSE;
 +        }
 +
 +      if (!(Item.fType & MF_SEPARATOR) &&
 +          !(Item.fState & (MFS_DISABLED | MFS_GRAYED)) )
 +      {
 +          if (MenuInfo.FocusedItem != Index)
 +            {
 +              MenuSwitchTracking(Mt, &MenuInfo, Index, Flags);
 +            }
 +
 +          /* If the popup menu is not already "popped" */
 +          if (0 == (Item.fState & MF_MOUSESELECT))
 +            {
 +              Mt->CurrentMenu = MenuShowSubPopup(Mt->OwnerWnd, &MenuInfo, FALSE, Flags);
 +            }
 +        }
 +
 +      MenuCleanupRosMenuItemInfo(&Item);
 +
 +      return TRUE;
 +    }
 +
 +  /* else the click was on the menu bar, finish the tracking */
 +
 +  return FALSE;
 +}
 +
 +/***********************************************************************
 + *           MenuButtonUp
 + *
 + * Return the value of MenuExecFocusedItem if
 + * the selected item was not a popup. Else open the popup.
 + * A -1 return value indicates that we go on with menu tracking.
 + *
 + */
 +static INT FASTCALL
 +MenuButtonUp(MTRACKER *Mt, HMENU PtMenu, UINT Flags)
 +{
 +  UINT Id;
 +  ROSMENUINFO MenuInfo;
 +  ROSMENUITEMINFO ItemInfo;
 +
 +  TRACE("%p hmenu=%x\n", Mt, PtMenu);
 +
 +  if (NULL != PtMenu)
 +    {
 +      Id = 0;
 +      if (! MenuGetRosMenuInfo(&MenuInfo, PtMenu))
 +        {
 +          return -1;
 +        }
 +
 +      if (! IS_SYSTEM_MENU(&MenuInfo))
 +        {
 +          Id = NtUserMenuItemFromPoint(Mt->OwnerWnd, MenuInfo.Self, Mt->Pt.x, Mt->Pt.y);
 +        }
 +      MenuInitRosMenuItemInfo(&ItemInfo);
 +      if (0 <= Id && MenuGetRosMenuItemInfo(MenuInfo.Self, Id, &ItemInfo) &&
 +          MenuInfo.FocusedItem == Id)
 +        {
 +          if (0 == (ItemInfo.fType & MF_POPUP))
 +            {
 +              INT ExecutedMenuId = MenuExecFocusedItem(Mt, &MenuInfo, Flags);
 +              MenuCleanupRosMenuItemInfo(&ItemInfo);
 +              return (ExecutedMenuId < 0) ? -1 : ExecutedMenuId;
 +            }
 +          MenuCleanupRosMenuItemInfo(&ItemInfo);
 +
 +          /* If we are dealing with the top-level menu            */
 +          /* and this is a click on an already "popped" item:     */
 +          /* Stop the menu tracking and close the opened submenus */
 +          if (Mt->TopMenu == MenuInfo.Self && MenuInfo.TimeToHide)
 +            {
 +              MenuCleanupRosMenuItemInfo(&ItemInfo);
 +              return 0;
 +            }
 +        }
 +      MenuCleanupRosMenuItemInfo(&ItemInfo);
 +      MenuInfo.TimeToHide = TRUE;
 +      MenuSetRosMenuInfo(&MenuInfo);
 +    }
 +
 +  return -1;
 +}
 +
 +/***********************************************************************
 + *           MenuPtMenu
 + *
 + * Walks menu chain trying to find a menu pt maps to.
 + */
 +static HMENU FASTCALL
 +MenuPtMenu(HMENU Menu, POINT Pt)
 +{
 +  extern LRESULT DefWndNCHitTest(HWND hWnd, POINT Point);
 +  ROSMENUINFO MenuInfo;
 +  ROSMENUITEMINFO ItemInfo;
 +  HMENU Ret = NULL;
 +  INT Ht;
 +
 +  if (! MenuGetRosMenuInfo(&MenuInfo, Menu))
 +    {
 +      return NULL;
 +    }
 +
 +  /* try subpopup first (if any) */
 +  if (NO_SELECTED_ITEM != MenuInfo.FocusedItem)
 +    {
 +      MenuInitRosMenuItemInfo(&ItemInfo);
 +      if (MenuGetRosMenuItemInfo(MenuInfo.Self, MenuInfo.FocusedItem, &ItemInfo) &&
 +          0 != (ItemInfo.fType & MF_POPUP) &&
 +          0 != (ItemInfo.fState & MF_MOUSESELECT))
 +        {
 +          Ret = MenuPtMenu(ItemInfo.hSubMenu, Pt);
 +          if (NULL != Ret)
 +            {
 +              MenuCleanupRosMenuItemInfo(&ItemInfo);
 +              return Ret;
 +            }
 +        }
 +      MenuCleanupRosMenuItemInfo(&ItemInfo);
 +    }
 +
 +  /* check the current window (avoiding WM_HITTEST) */
 +  Ht = DefWndNCHitTest(MenuInfo.Wnd, Pt);
 +  if (0 != (MenuInfo.Flags & MF_POPUP))
 +    {
 +      if (HTNOWHERE != Ht && HTERROR != Ht)
 +        {
 +          Ret = Menu;
 +        }
 +    }
 +  else if (HTSYSMENU == Ht)
 +    {
 +      Ret = NtUserGetSystemMenu(MenuInfo.Wnd, FALSE);
 +    }
 +  else if (HTMENU == Ht)
 +    {
 +      Ret = GetMenu(MenuInfo.Wnd);
 +    }
 +
 +  return Ret;
 +}
 +
 +/***********************************************************************
 + *           MenuMouseMove
 + *
 + * Return TRUE if we can go on with menu tracking.
 + */
 +static BOOL FASTCALL
 +MenuMouseMove(MTRACKER *Mt, HMENU PtMenu, UINT Flags)
 +{
 +  UINT Index;
 +  ROSMENUINFO MenuInfo;
 +  ROSMENUITEMINFO ItemInfo;
 +
 +  if (NULL != PtMenu)
 +    {
 +      if (! MenuGetRosMenuInfo(&MenuInfo, PtMenu))
 +        {
 +          return TRUE;
 +        }
 +      if (IS_SYSTEM_MENU(&MenuInfo))
 +        {
 +          Index = 0;
 +        }
 +      else
 +        {
 +          Index = NtUserMenuItemFromPoint(Mt->OwnerWnd, PtMenu, Mt->Pt.x, Mt->Pt.y);
 +        }
 +    }
 +  else
 +    {
 +      Index = NO_SELECTED_ITEM;
 +    }
 +
 +  if (NO_SELECTED_ITEM == Index)
 +    {
 +      if (Mt->CurrentMenu == MenuInfo.Self ||
 +          MenuGetRosMenuInfo(&MenuInfo, Mt->CurrentMenu))
 +        {
 +          MenuSelectItem(Mt->OwnerWnd, &MenuInfo, NO_SELECTED_ITEM,
 +                         TRUE, Mt->TopMenu);
 +        }
 +    }
 +  else if (MenuInfo.FocusedItem != Index)
 +    {
 +      MenuInitRosMenuItemInfo(&ItemInfo);
 +      if (MenuGetRosMenuItemInfo(MenuInfo.Self, Index, &ItemInfo) &&
 +           !(ItemInfo.fType & MF_SEPARATOR))
 +      {
 +          MenuSwitchTracking(Mt, &MenuInfo, Index, Flags);
 +        if (!(ItemInfo.fState & (MFS_DISABLED | MFS_GRAYED)))
 +              Mt->CurrentMenu = MenuShowSubPopup(Mt->OwnerWnd, &MenuInfo, FALSE, Flags);
 +      }
 +      MenuCleanupRosMenuItemInfo(&ItemInfo);
 +    }
 +
 +  return TRUE;
 +}
 +
 +/***********************************************************************
 + *           MenuGetSubPopup
 + *
 + * Return the handle of the selected sub-popup menu (if any).
 + */
 +static HMENU FASTCALL
 +MenuGetSubPopup(HMENU Menu)
 +{
 +  ROSMENUINFO MenuInfo;
 +  ROSMENUITEMINFO ItemInfo;
 +
 +  if (! MenuGetRosMenuInfo(&MenuInfo, Menu)
 +      || NO_SELECTED_ITEM == MenuInfo.FocusedItem)
 +    {
 +      return NULL;
 +    }
 +
 +  MenuInitRosMenuItemInfo(&ItemInfo);
 +  if (! MenuGetRosMenuItemInfo(MenuInfo.Self, MenuInfo.FocusedItem, &ItemInfo))
 +    {
 +      MenuCleanupRosMenuItemInfo(&ItemInfo);
 +      return NULL;
 +    }
 +  if (0 != (ItemInfo.fType & MF_POPUP) && 0 != (ItemInfo.fState & MF_MOUSESELECT))
 +    {
 +      MenuCleanupRosMenuItemInfo(&ItemInfo);
 +      return ItemInfo.hSubMenu;
 +    }
 +
 +  MenuCleanupRosMenuItemInfo(&ItemInfo);
 +  return NULL;
 +}
 +
 +/***********************************************************************
 + *           MenuDoNextMenu
 + *
 + * NOTE: WM_NEXTMENU documented in Win32 is a bit different.
 + */
 +static LRESULT FASTCALL
 +MenuDoNextMenu(MTRACKER* Mt, UINT Vk, UINT wFlags)
 +{
 +  ROSMENUINFO TopMenuInfo;
 +  ROSMENUINFO MenuInfo;
 +
 +  if (! MenuGetRosMenuInfo(&TopMenuInfo, Mt->TopMenu))
 +    {
 +      return (LRESULT) FALSE;
 +    }
 +
 +  if ((VK_LEFT == Vk && 0 == TopMenuInfo.FocusedItem)
 +      || (VK_RIGHT == Vk && TopMenuInfo.FocusedItem == TopMenuInfo.MenuItemCount - 1))
 +    {
 +      MDINEXTMENU NextMenu;
 +      HMENU NewMenu;
 +      HWND NewWnd;
 +      UINT Id = 0;
 +
 +      NextMenu.hmenuIn = (IS_SYSTEM_MENU(&TopMenuInfo)) ? GetSubMenu(Mt->TopMenu, 0) : Mt->TopMenu;
 +      NextMenu.hmenuNext = NULL;
 +      NextMenu.hwndNext = NULL;
 +      SendMessageW(Mt->OwnerWnd, WM_NEXTMENU, Vk, (LPARAM) &NextMenu);
 +
 +      TRACE("%p [%p] -> %p [%p]\n",
 +             Mt->CurrentMenu, Mt->OwnerWnd, NextMenu.hmenuNext, NextMenu.hwndNext );
 +
 +      if (NULL == NextMenu.hmenuNext || NULL == NextMenu.hwndNext)
 +        {
 +          DWORD Style = GetWindowLongPtrW(Mt->OwnerWnd, GWL_STYLE);
 +          NewWnd = Mt->OwnerWnd;
 +          if (IS_SYSTEM_MENU(&TopMenuInfo))
 +            {
 +              /* switch to the menu bar */
 +
 +              if (0 != (Style & WS_CHILD)
 +                  || NULL == (NewMenu = GetMenu(NewWnd)))
 +                {
 +                  return FALSE;
 +                }
 +
 +              if (VK_LEFT == Vk)
 +                {
 +                  if (! MenuGetRosMenuInfo(&MenuInfo, NewMenu))
 +                    {
 +                      return FALSE;
 +                    }
 +                  Id = MenuInfo.MenuItemCount - 1;
 +                }
 +            }
 +          else if (0 != (Style & WS_SYSMENU))
 +            {
 +              /* switch to the system menu */
 +              NewMenu = NtUserGetSystemMenu(NewWnd, FALSE);
 +            }
 +          else
 +            {
 +              return FALSE;
 +            }
 +        }
 +      else    /* application returned a new menu to switch to */
 +        {
 +          NewMenu = NextMenu.hmenuNext;
 +          NewWnd = NextMenu.hwndNext;
 +
 +          if (IsMenu(NewMenu) && IsWindow(NewWnd))
 +            {
 +              DWORD Style = GetWindowLongPtrW(NewWnd, GWL_STYLE);
 +
 +              if (0 != (Style & WS_SYSMENU)
 +                  && GetSystemMenu(NewWnd, FALSE) == NewMenu)
 +                {
 +                  /* get the real system menu */
 +                  NewMenu = NtUserGetSystemMenu(NewWnd, FALSE);
 +                }
 +              else if (0 != (Style & WS_CHILD) || GetMenu(NewWnd) != NewMenu)
 +                {
 +                  /* FIXME: Not sure what to do here;
 +                   * perhaps try to track NewMenu as a popup? */
 +
 +                  WARN(" -- got confused.\n");
 +                  return FALSE;
 +                }
 +            }
 +          else
 +            {
 +              return FALSE;
 +            }
 +        }
 +
 +      if (NewMenu != Mt->TopMenu)
 +        {
 +          MenuSelectItem(Mt->OwnerWnd, &TopMenuInfo, NO_SELECTED_ITEM,
 +                         FALSE, 0 );
 +          if (Mt->CurrentMenu != Mt->TopMenu)
 +            {
 +              MenuHideSubPopups(Mt->OwnerWnd, &TopMenuInfo, FALSE, wFlags);
 +            }
 +        }
 +
 +      if (NewWnd != Mt->OwnerWnd)
 +        {
 +          Mt->OwnerWnd = NewWnd;
 +          SetCapture(Mt->OwnerWnd);
 +          (void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, Mt->OwnerWnd);
 +        }
 +
 +      Mt->TopMenu = Mt->CurrentMenu = NewMenu; /* all subpopups are hidden */
 +      if (MenuGetRosMenuInfo(&TopMenuInfo, Mt->TopMenu))
 +        {
 +          MenuSelectItem(Mt->OwnerWnd, &TopMenuInfo, Id, TRUE, 0);
 +        }
 +
 +      return TRUE;
 +    }
 +
 +  return FALSE;
 +}
 +
 +/***********************************************************************
 + *           MenuSuspendPopup
 + *
 + * The idea is not to show the popup if the next input message is
 + * going to hide it anyway.
 + */
 +static BOOL FASTCALL
 +MenuSuspendPopup(MTRACKER* Mt, UINT Message)
 +{
 +  MSG Msg;
 +
 +  Msg.hwnd = Mt->OwnerWnd;
 +
 +  PeekMessageW(&Msg, 0, 0, 0, PM_NOYIELD | PM_REMOVE);
 +  Mt->TrackFlags |= TF_SKIPREMOVE;
 +
 +  switch (Message)
 +    {
 +      case WM_KEYDOWN:
 +        PeekMessageW(&Msg, 0, 0, 0, PM_NOYIELD | PM_NOREMOVE);
 +        if (WM_KEYUP == Msg.message || WM_PAINT == Msg.message)
 +          {
 +            PeekMessageW(&Msg, 0, 0, 0, PM_NOYIELD | PM_REMOVE);
 +            PeekMessageW(&Msg, 0, 0, 0, PM_NOYIELD | PM_NOREMOVE);
 +            if (WM_KEYDOWN == Msg.message
 +                && (VK_LEFT == Msg.wParam || VK_RIGHT == Msg.wParam))
 +              {
 +                Mt->TrackFlags |= TF_SUSPENDPOPUP;
 +                return TRUE;
 +              }
 +          }
 +        break;
 +    }
 +
 +  /* failures go through this */
 +  Mt->TrackFlags &= ~TF_SUSPENDPOPUP;
 +
 +  return FALSE;
 +}
 +
 +/***********************************************************************
 + *           MenuKeyEscape
 + *
 + * Handle a VK_ESCAPE key event in a menu.
 + */
 +static BOOL FASTCALL
 +MenuKeyEscape(MTRACKER *Mt, UINT Flags)
 +{
 +  BOOL EndMenu = TRUE;
 +  ROSMENUINFO MenuInfo;
 +  HMENU MenuTmp, MenuPrev;
 +
 +  if (Mt->CurrentMenu != Mt->TopMenu)
 +    {
 +      if (MenuGetRosMenuInfo(&MenuInfo, Mt->CurrentMenu)
 +          && 0 != (MenuInfo.Flags & MF_POPUP))
 +        {
 +          MenuPrev = MenuTmp = Mt->TopMenu;
 +
 +          /* close topmost popup */
 +          while (MenuTmp != Mt->CurrentMenu)
 +            {
 +              MenuPrev = MenuTmp;
 +              MenuTmp = MenuGetSubPopup(MenuPrev);
 +            }
 +
 +          if (MenuGetRosMenuInfo(&MenuInfo, MenuPrev))
 +            {
 +              MenuHideSubPopups(Mt->OwnerWnd, &MenuInfo, TRUE, Flags);
 +            }
 +          Mt->CurrentMenu = MenuPrev;
 +          EndMenu = FALSE;
 +        }
 +    }
 +
 +  return EndMenu;
 +}
 +
 +/***********************************************************************
 + *           MenuKeyLeft
 + *
 + * Handle a VK_LEFT key event in a menu.
 + */
 +static void FASTCALL
 +MenuKeyLeft(MTRACKER* Mt, UINT Flags)
 +{
 +  ROSMENUINFO MenuInfo;
 +  ROSMENUINFO TopMenuInfo;
 +  ROSMENUINFO PrevMenuInfo;
 +  HMENU MenuTmp, MenuPrev;
 +  UINT PrevCol;
 +
 +  MenuPrev = MenuTmp = Mt->TopMenu;
 +
 +  if (! MenuGetRosMenuInfo(&MenuInfo, Mt->CurrentMenu))
 +    {
 +      return;
 +    }
 +
 +  /* Try to move 1 column left (if possible) */
 +  if (NO_SELECTED_ITEM != (PrevCol = MenuGetStartOfPrevColumn(&MenuInfo)))
 +    {
 +      if (MenuGetRosMenuInfo(&MenuInfo, Mt->CurrentMenu))
 +        {
 +          MenuSelectItem(Mt->OwnerWnd, &MenuInfo, PrevCol, TRUE, 0);
 +        }
 +      return;
 +    }
 +
 +  /* close topmost popup */
 +  while (MenuTmp != Mt->CurrentMenu)
 +    {
 +      MenuPrev = MenuTmp;
 +      MenuTmp = MenuGetSubPopup(MenuPrev);
 +    }
 +
 +  if (! MenuGetRosMenuInfo(&PrevMenuInfo, MenuPrev))
 +    {
 +      return;
 +    }
 +  MenuHideSubPopups(Mt->OwnerWnd, &PrevMenuInfo, TRUE, Flags);
 +  Mt->CurrentMenu = MenuPrev;
 +
 +  if (! MenuGetRosMenuInfo(&TopMenuInfo, Mt->TopMenu))
 +    {
 +      return;
 +    }
 +  if ((MenuPrev == Mt->TopMenu) && 0 == (TopMenuInfo.Flags & MF_POPUP))
 +    {
 +      /* move menu bar selection if no more popups are left */
 +
 +      if (! MenuDoNextMenu(Mt, VK_LEFT, Flags))
 +        {
 +          MenuMoveSelection(Mt->OwnerWnd, &TopMenuInfo, ITEM_PREV);
 +        }
 +
 +      if (MenuPrev != MenuTmp || 0 != (Mt->TrackFlags & TF_SUSPENDPOPUP))
 +        {
 +          /* A sublevel menu was displayed - display the next one
 +           * unless there is another displacement coming up */
 +
 +          if (! MenuSuspendPopup(Mt, WM_KEYDOWN)
 +              && MenuGetRosMenuInfo(&TopMenuInfo, Mt->TopMenu))
 +            {
 +              Mt->CurrentMenu = MenuShowSubPopup(Mt->OwnerWnd, &TopMenuInfo,
 +                                                 TRUE, Flags);
 +            }
 +        }
 +    }
 +}
 +
 +/***********************************************************************
 + *           MenuKeyRight
 + *
 + * Handle a VK_RIGHT key event in a menu.
 + */
 +static void FASTCALL MenuKeyRight(MTRACKER *Mt, UINT Flags)
 +{
 +    HMENU hmenutmp;
 +    ROSMENUINFO MenuInfo;
 +    ROSMENUINFO CurrentMenuInfo;
 +    UINT NextCol;
 +
 +    TRACE("MenuKeyRight called, cur %p, top %p.\n",
 +         Mt->CurrentMenu, Mt->TopMenu);
 +
 +    if (! MenuGetRosMenuInfo(&MenuInfo, Mt->TopMenu)) return;
 +    if ((MenuInfo.Flags & MF_POPUP) || (Mt->CurrentMenu != Mt->TopMenu))
 +    {
 +      /* If already displaying a popup, try to display sub-popup */
 +
 +      hmenutmp = Mt->CurrentMenu;
 +      if (MenuGetRosMenuInfo(&CurrentMenuInfo, Mt->CurrentMenu))
 +        {
 +          Mt->CurrentMenu = MenuShowSubPopup(Mt->OwnerWnd, &CurrentMenuInfo, TRUE, Flags);
 +        }
 +
 +      /* if subpopup was displayed then we are done */
 +      if (hmenutmp != Mt->CurrentMenu) return;
 +    }
 +
 +  if (! MenuGetRosMenuInfo(&CurrentMenuInfo, Mt->CurrentMenu))
 +    {
 +      return;
 +    }
 +
 +  /* Check to see if there's another column */
 +  if (NO_SELECTED_ITEM != (NextCol = MenuGetStartOfNextColumn(&CurrentMenuInfo)))
 +    {
 +      TRACE("Going to %d.\n", NextCol);
 +      if (MenuGetRosMenuInfo(&MenuInfo, Mt->CurrentMenu))
 +        {
 +          MenuSelectItem(Mt->OwnerWnd, &MenuInfo, NextCol, TRUE, 0);
 +        }
 +      return;
 +    }
 +
 +  if (0 == (MenuInfo.Flags & MF_POPUP))       /* menu bar tracking */
 +    {
 +      if (Mt->CurrentMenu != Mt->TopMenu)
 +        {
 +          MenuHideSubPopups(Mt->OwnerWnd, &MenuInfo, FALSE, Flags);
 +          hmenutmp = Mt->CurrentMenu = Mt->TopMenu;
 +        }
 +      else
 +        {
 +          hmenutmp = NULL;
 +        }
 +
 +      /* try to move to the next item */
 +      if ( !MenuDoNextMenu(Mt, VK_RIGHT, Flags))
 +          MenuMoveSelection(Mt->OwnerWnd, &MenuInfo, ITEM_NEXT);
 +
 +      if ( hmenutmp || Mt->TrackFlags & TF_SUSPENDPOPUP )
 +        {
 +          if (! MenuSuspendPopup(Mt, WM_KEYDOWN)
 +              && MenuGetRosMenuInfo(&MenuInfo, Mt->TopMenu))
 +            {
 +              Mt->CurrentMenu = MenuShowSubPopup(Mt->OwnerWnd, &MenuInfo,
 +                                                 TRUE, Flags);
 +            }
 +        }
 +    }
 +}
 +
 +/***********************************************************************
 + *           MenuTrackMenu
 + *
 + * Menu tracking code.
 + */
 +static INT FASTCALL MenuTrackMenu(HMENU hmenu, UINT wFlags, INT x, INT y,
 +                            HWND hwnd, const RECT *lprect )
 +{
 +    MSG msg;
 +    ROSMENUINFO MenuInfo;
 +    ROSMENUITEMINFO ItemInfo;
 +    BOOL fRemove;
 +    INT executedMenuId = -1;
 +    MTRACKER mt;
++    HWND capture_win;
 +    BOOL enterIdleSent = FALSE;
 +
 +    mt.TrackFlags = 0;
 +    mt.CurrentMenu = hmenu;
 +    mt.TopMenu = hmenu;
 +    mt.OwnerWnd = hwnd;
 +    mt.Pt.x = x;
 +    mt.Pt.y = y;
 +
 +    TRACE("hmenu=%p flags=0x%08x (%d,%d) hwnd=%x (%ld,%ld)-(%ld,%ld)\n",
 +         hmenu, wFlags, x, y, hwnd, lprect ? lprect->left : 0, lprect ? lprect->top : 0,
 +         lprect ? lprect->right : 0, lprect ? lprect->bottom : 0);
 +
 +    if (!IsMenu(hmenu))
 +    {
 +        WARN("Invalid menu handle %p\n", hmenu);
 +        SetLastError( ERROR_INVALID_MENU_HANDLE );
 +        return FALSE;
 +    }
 +
 +    fEndMenu = FALSE;
 +    if (! MenuGetRosMenuInfo(&MenuInfo, hmenu))
 +    {
 +        return FALSE;
 +    }
 +
 +    if (wFlags & TPM_BUTTONDOWN)
 +    {
 +        /* Get the result in order to start the tracking or not */
 +        fRemove = MenuButtonDown( &mt, hmenu, wFlags );
 +        fEndMenu = !fRemove;
 +    }
 +
-     FIXME("MenuTrackMenu 1\n");
++    if (wFlags & TF_ENDMENU) fEndMenu = TRUE;
++
++    /* owner may not be visible when tracking a popup, so use the menu itself */
++    capture_win = (wFlags & TPM_POPUPMENU) ? MenuInfo.Wnd : mt.OwnerWnd;
++    (void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, capture_win); // 1
++    SetCapture(capture_win);                                          // 2
 +
-             //FIXME("MenuTrackMenu loop 1\n");
 +    while (! fEndMenu)
 +    {
++        BOOL ErrorExit = FALSE;
 +        PVOID menu = ValidateHandle(mt.CurrentMenu, VALIDATE_TYPE_MENU);
 +        if (!menu) /* sometimes happens if I do a window manager close */
 +           break;
 +
 +        /* we have to keep the message in the queue until it's
 +         * clear that menu loop is not over yet. */
 +
 +        for (;;)
 +        {
 +            if (PeekMessageW( &msg, 0, 0, 0, PM_NOREMOVE ))
 +            {
 +                if (!CallMsgFilterW( &msg, MSGF_MENU )) break;
 +                /* remove the message from the queue */
 +                PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
 +            }
 +            else
 +            {
++                /* ReactOS Check */
++                if (!ValidateHwnd(mt.OwnerWnd) || !ValidateHwnd(MenuInfo.Wnd))
++                {
++                   ErrorExit = TRUE; // Do not wait on dead windows, now test_capture_4 works.
++                   break;
++                }
 +                if (!enterIdleSent)
 +                {
 +                  HWND win = MenuInfo.Flags & MF_POPUP ? MenuInfo.Wnd : NULL;
 +                  enterIdleSent = TRUE;
 +                  SendMessageW( mt.OwnerWnd, WM_ENTERIDLE, MSGF_MENU, (LPARAM) win);
 +                }
 +                WaitMessage();
 +            }
-             //FIXME("MenuTrackMenu loop 2\n");
 +        }
 +
++        if (ErrorExit) break; // Gracefully dropout.
++
 +        /* check if EndMenu() tried to cancel us, by posting this message */
 +        if (msg.message == WM_CANCELMODE)
 +        {
 +            /* we are now out of the loop */
 +            fEndMenu = TRUE;
 +
 +            /* remove the message from the queue */
 +            PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
 +
 +            /* break out of internal loop, ala ESCAPE */
 +            break;
 +        }
 +
 +        TranslateMessage( &msg );
 +        mt.Pt = msg.pt;
 +
 +        if ( (msg.hwnd == MenuInfo.Wnd) || (msg.message!=WM_TIMER) )
 +            enterIdleSent=FALSE;
 +
 +        fRemove = FALSE;
 +        if ((msg.message >= WM_MOUSEFIRST) && (msg.message <= WM_MOUSELAST))
 +        {
 +            /*
 +             * Use the mouse coordinates in lParam instead of those in the MSG
 +             * struct to properly handle synthetic messages. They are already
 +             * in screen coordinates.
 +             */
 +            mt.Pt.x = (short)LOWORD(msg.lParam);
 +            mt.Pt.y = (short)HIWORD(msg.lParam);
 +
 +            /* Find a menu for this mouse event */
 +            hmenu = MenuPtMenu(mt.TopMenu, mt.Pt);
 +
 +            switch(msg.message)
 +            {
 +                /* no WM_NC... messages in captured state */
 +
 +                case WM_RBUTTONDBLCLK:
 +                case WM_RBUTTONDOWN:
 +                     if (!(wFlags & TPM_RIGHTBUTTON)) break;
 +                    /* fall through */
 +                case WM_LBUTTONDBLCLK:
 +                case WM_LBUTTONDOWN:
 +                    /* If the message belongs to the menu, removes it from the queue */
 +                    /* Else, end menu tracking */
 +                    fRemove = MenuButtonDown(&mt, hmenu, wFlags);
 +                    fEndMenu = !fRemove;
 +                    break;
 +
 +                case WM_RBUTTONUP:
 +                    if (!(wFlags & TPM_RIGHTBUTTON)) break;
 +                    /* fall through */
 +                case WM_LBUTTONUP:
 +                    /* Check if a menu was selected by the mouse */
 +                    if (hmenu)
 +                    {
 +                        executedMenuId = MenuButtonUp( &mt, hmenu, wFlags);
 +                        TRACE("executedMenuId %d\n", executedMenuId);
 +
 +                    /* End the loop if executedMenuId is an item ID */
 +                    /* or if the job was done (executedMenuId = 0). */
 +                        fEndMenu = fRemove = (executedMenuId != -1);
 +                    }
 +                    /* No menu was selected by the mouse */
 +                    /* if the function was called by TrackPopupMenu, continue
 +                       with the menu tracking. If not, stop it */
 +                    else
 +                        fEndMenu = ((wFlags & TPM_POPUPMENU) ? FALSE : TRUE);
 +
 +                    break;
 +
 +                case WM_MOUSEMOVE:
 +                    /* the selected menu item must be changed every time */
 +                    /* the mouse moves. */
 +
 +                    if (hmenu)
 +                        fEndMenu |= !MenuMouseMove( &mt, hmenu, wFlags );
 +
 +              } /* switch(msg.message) - mouse */
 +          }
 +        else if ((msg.message >= WM_KEYFIRST) && (msg.message <= WM_KEYLAST))
 +        {
 +            fRemove = TRUE;  /* Keyboard messages are always removed */
 +            switch(msg.message)
 +            {
 +                case WM_KEYDOWN:
 +                case WM_SYSKEYDOWN:
 +                switch(msg.wParam)
 +                {
 +                    case VK_MENU:
 +                    case VK_F10:
 +                        fEndMenu = TRUE;
 +                         break;
 +
 +                    case VK_HOME:
 +                    case VK_END:
 +                        if (MenuGetRosMenuInfo(&MenuInfo, mt.CurrentMenu))
 +                        {
 +                            MenuSelectItem(mt.OwnerWnd, &MenuInfo,
 +                                    NO_SELECTED_ITEM, FALSE, 0 );
 +                            MenuMoveSelection(mt.OwnerWnd, &MenuInfo,
 +                                              VK_HOME == msg.wParam ? ITEM_NEXT : ITEM_PREV);
 +                        }
 +                        break;
 +
 +                    case VK_UP:
 +                    case VK_DOWN: /* If on menu bar, pull-down the menu */
 +                        if (MenuGetRosMenuInfo(&MenuInfo, mt.CurrentMenu))
 +                        {
 +                            if (!(MenuInfo.Flags & MF_POPUP))
 +                            {
 +                                if (MenuGetRosMenuInfo(&MenuInfo, mt.TopMenu))
 +                                    mt.CurrentMenu = MenuShowSubPopup(mt.OwnerWnd, &MenuInfo, TRUE, wFlags);
 +                            }
 +                            else      /* otherwise try to move selection */
 +                                MenuMoveSelection(mt.OwnerWnd, &MenuInfo,
 +                                       (msg.wParam == VK_UP)? ITEM_PREV : ITEM_NEXT );
 +                        }
 +                        break;
 +
 +                    case VK_LEFT:
 +                        MenuKeyLeft( &mt, wFlags );
 +                        break;
 +
 +                    case VK_RIGHT:
 +                        MenuKeyRight( &mt, wFlags );
 +                        break;
 +
 +                    case VK_ESCAPE:
 +                        fEndMenu = MenuKeyEscape(&mt, wFlags);
 +                        break;
 +
 +                    case VK_F1:
 +                    {
 +                        HELPINFO hi;
 +                        hi.cbSize = sizeof(HELPINFO);
 +                        hi.iContextType = HELPINFO_MENUITEM;
 +                        if (MenuGetRosMenuInfo(&MenuInfo, mt.CurrentMenu))
 +                        {
 +                            if (MenuInfo.FocusedItem == NO_SELECTED_ITEM)
 +                                hi.iCtrlId = 0;
 +                            else
 +                            {
 +                                MenuInitRosMenuItemInfo(&ItemInfo);
 +                                if (MenuGetRosMenuItemInfo(MenuInfo.Self,
 +                                                           MenuInfo.FocusedItem,
 +                                                           &ItemInfo))
 +                                {
 +                                    hi.iCtrlId = ItemInfo.wID;
 +                                }
 +                                else
 +                                {
 +                                    hi.iCtrlId = 0;
 +                                }
 +                                MenuCleanupRosMenuItemInfo(&ItemInfo);
 +                            }
 +                        }
 +                        hi.hItemHandle = hmenu;
 +                        hi.dwContextId = MenuInfo.dwContextHelpID;
 +                        hi.MousePos = msg.pt;
 +                        SendMessageW(hwnd, WM_HELP, 0, (LPARAM)&hi);
 +                        break;
 +                    }
 +
 +                    default:
 +                        break;
 +                }
 +                break;  /* WM_KEYDOWN */
 +
 +                case WM_CHAR:
 +                case WM_SYSCHAR:
 +                {
 +                    UINT pos;
 +
 +                    if (! MenuGetRosMenuInfo(&MenuInfo, mt.CurrentMenu)) break;
 +                    if (msg.wParam == L'\r' || msg.wParam == L' ')
 +                    {
 +                        executedMenuId = MenuExecFocusedItem(&mt, &MenuInfo, wFlags);
 +                        fEndMenu = (executedMenuId != -2);
 +                        break;
 +                    }
 +
 +                    /* Hack to avoid control chars. */
 +                    /* We will find a better way real soon... */
 +                    if (msg.wParam < 32) break;
 +
 +                    pos = MenuFindItemByKey(mt.OwnerWnd, &MenuInfo,
 +                                          LOWORD(msg.wParam), FALSE);
 +                    if (pos == (UINT)-2) fEndMenu = TRUE;
 +                    else if (pos == (UINT)-1) MessageBeep(0);
 +                    else
 +                    {
 +                        MenuSelectItem(mt.OwnerWnd, &MenuInfo, pos,
 +                            TRUE, 0);
 +                        executedMenuId = MenuExecFocusedItem(&mt, &MenuInfo, wFlags);
 +                        fEndMenu = (executedMenuId != -2);
 +                    }
 +                }
 +                break;
 +            }  /* switch(msg.message) - kbd */
 +        }
 +        else
 +        {
 +            PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
 +            DispatchMessageW( &msg );
-         //FIXME("MenuTrackMenu loop 3\n");
 +            continue;
 +        }
 +
 +        if (!fEndMenu) fRemove = TRUE;
 +
 +        /* finally remove message from the queue */
 +
 +        if (fRemove && !(mt.TrackFlags & TF_SKIPREMOVE) )
 +            PeekMessageW( &msg, 0, msg.message, msg.message, PM_REMOVE );
 +        else mt.TrackFlags &= ~TF_SKIPREMOVE;
-     FIXME("MenuTrackMenu 2\n");
 +    }
-     MenuGetRosMenuInfo(&MenuInfo, hMenu);
 +
 +    (void)NtUserSetGUIThreadHandle(MSQ_STATE_MENUOWNER, NULL);
 +    SetCapture(NULL);  /* release the capture */
 +
 +    /* If dropdown is still painted and the close box is clicked on
 +       then the menu will be destroyed as part of the DispatchMessage above.
 +       This will then invalidate the menu handle in mt.hTopMenu. We should
 +       check for this first.  */
 +    if( IsMenu( mt.TopMenu ) )
 +    {
 +        if (IsWindow(mt.OwnerWnd))
 +        {
 +            if (MenuGetRosMenuInfo(&MenuInfo, mt.TopMenu))
 +            {
 +                MenuHideSubPopups(mt.OwnerWnd, &MenuInfo, FALSE, wFlags);
 +
 +                if (MenuInfo.Flags & MF_POPUP)
 +                {
 +                    IntNotifyWinEvent(EVENT_SYSTEM_MENUPOPUPEND, MenuInfo.Wnd, OBJID_CLIENT, CHILDID_SELF, 0);
 +                    DestroyWindow(MenuInfo.Wnd);
 +                    MenuInfo.Wnd = NULL;
 +
 +                    if (!(MenuInfo.Flags & TPM_NONOTIFY))
 +                      SendMessageW( mt.OwnerWnd, WM_UNINITMENUPOPUP, (WPARAM)mt.TopMenu,
 +                                 MAKELPARAM(0, IS_SYSTEM_MENU(&MenuInfo)) );
 +
 +                }
 +                MenuSelectItem( mt.OwnerWnd, &MenuInfo, NO_SELECTED_ITEM, FALSE, 0 );
 +            }
 +
 +            SendMessageW( mt.OwnerWnd, WM_MENUSELECT, MAKEWPARAM(0, 0xffff), 0 );
 +        }
 +
 +        /* Reset the variable for hiding menu */
 +        if (MenuGetRosMenuInfo(&MenuInfo, mt.TopMenu))
 +        {
 +            MenuInfo.TimeToHide = FALSE;
 +            MenuSetRosMenuInfo(&MenuInfo);
 +        }
 +    }
 +
 +    /* The return value is only used by TrackPopupMenu */
 +    if (!(wFlags & TPM_RETURNCMD)) return TRUE;
 +    if (executedMenuId == -1) executedMenuId = 0;
 +    return executedMenuId;
 +}
 +
 +/***********************************************************************
 + *           MenuInitTracking
 + */
 +static BOOL FASTCALL MenuInitTracking(HWND hWnd, HMENU hMenu, BOOL bPopup, UINT wFlags)
 +{
 +    ROSMENUINFO MenuInfo;
 +
 +    TRACE("hwnd=%p hmenu=%p\n", hWnd, hMenu);
 +
 +    HideCaret(0);
 +
-     if(MenuInfo.Self == hMenu)
 +    /* This makes the menus of applications built with Delphi work.
 +     * It also enables menus to be displayed in more than one window,
 +     * but there are some bugs left that need to be fixed in this case.
 +     */
-     if (wParam & HTSYSMENU)
-     {
-         /* prevent sysmenu activation for managed windows on Alt down/up */
- //        if (GetPropA( hwnd, "__wine_x11_managed" ))
-             wFlags |= TF_ENDMENU; /* schedule end of menu tracking */
-     }
-     else
++    if (MenuGetRosMenuInfo(&MenuInfo, hMenu))
 +    {
 +        MenuInfo.Wnd = hWnd;
 +        MenuSetRosMenuInfo(&MenuInfo);
 +    }
 +
 +    /* Send WM_ENTERMENULOOP and WM_INITMENU message only if TPM_NONOTIFY flag is not specified */
 +    if (!(wFlags & TPM_NONOTIFY))
 +       SendMessageW( hWnd, WM_ENTERMENULOOP, bPopup, 0 );
 +
 +    SendMessageW( hWnd, WM_SETCURSOR, (WPARAM)hWnd, HTCAPTION );
 +
 +    if (!(wFlags & TPM_NONOTIFY))
 +    {
 +       SendMessageW( hWnd, WM_INITMENU, (WPARAM)hMenu, 0 );
 +       /* If an app changed/recreated menu bar entries in WM_INITMENU
 +        * menu sizes will be recalculated once the menu created/shown.
 +        */
 +
 +       if (!MenuInfo.Height)
 +       {
 +          /* app changed/recreated menu bar entries in WM_INITMENU
 +             Recalculate menu sizes else clicks will not work */
 +             SetWindowPos(hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
 +                       SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED );
 +
 +       }
 +    }
 +
 +    IntNotifyWinEvent( EVENT_SYSTEM_MENUSTART,
 +                       hWnd,
 +                       MenuInfo.Flags & MF_SYSMENU ? OBJID_SYSMENU : OBJID_MENU,
 +                       CHILDID_SELF, 0);
 +    return TRUE;
 +}
 +/***********************************************************************
 + *           MenuExitTracking
 + */
 +static BOOL FASTCALL MenuExitTracking(HWND hWnd, BOOL bPopup)
 +{
 +    TRACE("hwnd=%p\n", hWnd);
 +
 +    IntNotifyWinEvent( EVENT_SYSTEM_MENUEND, hWnd, OBJID_WINDOW, CHILDID_SELF, 0);
 +    SendMessageW( hWnd, WM_EXITMENULOOP, bPopup, 0 );
 +    ShowCaret(0);
 +    top_popup = 0;
 +    top_popup_hmenu = NULL;
 +    return TRUE;
 +}
 +
 +/***********************************************************************
 + *           MenuTrackMouseMenuBar
 + *
 + * Menu-bar tracking upon a mouse event. Called from NC_HandleSysCommand().
 + */
 +VOID MenuTrackMouseMenuBar( HWND hWnd, ULONG ht, POINT pt)
 +{
 +    HMENU hMenu = (ht == HTSYSMENU) ? NtUserGetSystemMenu( hWnd, FALSE) : GetMenu(hWnd);
 +    UINT wFlags = TPM_BUTTONDOWN | TPM_LEFTALIGN | TPM_LEFTBUTTON;
 +
 +    TRACE("wnd=%p ht=0x%04x (%ld,%ld)\n", hWnd, ht, pt.x, pt.y);
 +
 +    if (IsMenu(hMenu))
 +    {
 +        /* map point to parent client coordinates */
 +        HWND Parent = GetAncestor(hWnd, GA_PARENT );
 +        if (Parent != GetDesktopWindow())
 +        {
 +            ScreenToClient(Parent, &pt);
 +        }
 +
 +        MenuInitTracking(hWnd, hMenu, FALSE, wFlags);
 +        MenuTrackMenu(hMenu, wFlags, pt.x, pt.y, hWnd, NULL);
 +        MenuExitTracking(hWnd, FALSE);
 +    }
 +}
 +
 +
 +/***********************************************************************
 + *           MenuTrackKbdMenuBar
 + *
 + * Menu-bar tracking upon a keyboard event. Called from NC_HandleSysCommand().
 + */
 +VOID MenuTrackKbdMenuBar(HWND hwnd, UINT wParam, WCHAR wChar)
 +{
 +    UINT uItem = NO_SELECTED_ITEM;
 +    HMENU hTrackMenu;
 +    ROSMENUINFO MenuInfo;
 +    UINT wFlags = TPM_LEFTALIGN | TPM_LEFTBUTTON;
 +
 +    TRACE("hwnd %p wParam 0x%04x wChar 0x%04x\n", hwnd, wParam, wChar);
 +
 +    /* find window that has a menu */
 +
 +    while (!((GetWindowLongPtrW( hwnd, GWL_STYLE ) &
 +                                         (WS_CHILD | WS_POPUP)) != WS_CHILD))
 +        if (!(hwnd = GetAncestor( hwnd, GA_PARENT ))) return;
 +
 +    /* check if we have to track a system menu */
 +
 +    hTrackMenu = GetMenu( hwnd );
 +    if (!hTrackMenu || IsIconic(hwnd) || wChar == ' ' )
 +    {
 +        if (!(GetWindowLongPtrW( hwnd, GWL_STYLE ) & WS_SYSMENU)) return;
 +        hTrackMenu = NtUserGetSystemMenu(hwnd, FALSE);
 +        uItem = 0;
 +        wParam |= HTSYSMENU; /* prevent item lookup */
 +    }
 +
 +    if (!IsMenu( hTrackMenu )) return;
 +
 +    MenuInitTracking( hwnd, hTrackMenu, FALSE, wFlags );
 +
 +    if (! MenuGetRosMenuInfo(&MenuInfo, hTrackMenu))
 +    {
 +      goto track_menu;
 +    }
 +
 +    if( wChar && wChar != ' ' )
 +    {
 +        uItem = MenuFindItemByKey( hwnd, &MenuInfo, wChar, (wParam & HTSYSMENU) );
 +        if ( uItem >= (UINT)(-2) )
 +        {
 +            if( uItem == (UINT)(-1) ) MessageBeep(0);
 +            /* schedule end of menu tracking */
 +            wFlags |= TF_ENDMENU;
 +            goto track_menu;
 +        }
 +    }
 +
 +    MenuSelectItem( hwnd, &MenuInfo, uItem, TRUE, 0 );
 +
++    if (!(wParam & HTSYSMENU) || wChar == ' ')
 +    {
 +        if( uItem == NO_SELECTED_ITEM )
 +            MenuMoveSelection( hwnd, &MenuInfo, ITEM_NEXT );
 +        else
 +            PostMessageW( hwnd, WM_KEYDOWN, VK_DOWN, 0L );
 +    }
 +
 +track_menu:
 +    MenuTrackMenu( hTrackMenu, wFlags, 0, 0, hwnd, NULL );
 +    MenuExitTracking( hwnd, FALSE );
 +
 +}
 +
 +/**********************************************************************
 + *           TrackPopupMenuEx   (USER32.@)
 + */
 +BOOL WINAPI TrackPopupMenuEx( HMENU Menu, UINT Flags, int x, int y,
 +                              HWND Wnd, LPTPMPARAMS Tpm)
 +{
 +    BOOL ret = FALSE;
 +    ROSMENUINFO MenuInfo;
 +
 +    if (!IsMenu(Menu))
 +    {
 +      SetLastError( ERROR_INVALID_MENU_HANDLE );
 +      return FALSE;
 +    }
 +
++    /* ReactOS Check */
++    if (!ValidateHwnd(Wnd))
++    {
++       return FALSE;
++    }
++
 +    MenuGetRosMenuInfo(&MenuInfo, Menu);
 +    if (IsWindow(MenuInfo.Wnd))
 +    {
 +        SetLastError( ERROR_POPUP_ALREADY_ACTIVE );
 +        return FALSE;
 +    }
 +
 +    MenuInitTracking(Wnd, Menu, TRUE, Flags);
 +
 +    /* Send WM_INITMENUPOPUP message only if TPM_NONOTIFY flag is not specified */
 +    if (!(Flags & TPM_NONOTIFY))
 +        SendMessageW(Wnd, WM_INITMENUPOPUP, (WPARAM) Menu, 0);
 +
 +    if (MenuShowPopup(Wnd, Menu, 0, Flags, x, y, 0, 0 ))
 +       ret = MenuTrackMenu(Menu, Flags | TPM_POPUPMENU, 0, 0, Wnd,
 +                           Tpm ? &Tpm->rcExclude : NULL);
 +    MenuExitTracking(Wnd, TRUE);
 +    return ret;
 +}
 +
 +/**********************************************************************
 + *           TrackPopupMenu     (USER32.@)
 + */
 +BOOL WINAPI TrackPopupMenu( HMENU Menu, UINT Flags, int x, int y,
 +                            int Reserved, HWND Wnd, CONST RECT *Rect)
 +{
 +    return TrackPopupMenuEx( Menu, Flags, x, y, Wnd, NULL);
 +}
 +
 +/*
 + *  From MSDN:
 + *  The MFT_BITMAP, MFT_SEPARATOR, and MFT_STRING values cannot be combined
 + *  with one another. Also MFT_OWNERDRAW. Set fMask to MIIM_TYPE to use fType.
 + *
 + *  Windows 2K/XP: fType is used only if fMask has a value of MIIM_FTYPE.
 + *
 + *  MIIM_TYPE: Retrieves or sets the fType and dwTypeData members. Windows
 + *  2K/XP: MIIM_TYPE is replaced by  MIIM_BITMAP, MIIM_FTYPE, and MIIM_STRING.
 + *  MFT_STRING is replaced by MIIM_STRING.
 + *  (So, I guess we should use MIIM_STRING only for strings?)
 + *
 + *  MIIM_FTYPE: Windows 2K/Windows XP: Retrieves or sets the fType member.
 + *
 + *  Based on wine, SetMenuItemInfo_common:
 + *  1) set MIIM_STRING | MIIM_FTYPE | MIIM_BITMAP any one with MIIM_TYPE,
 + *     it will result in a error.
 + *  2) set menu mask to MIIM_FTYPE and MFT_BITMAP ftype it will result in a error.
 + *     These conditions are addressed in Win32k IntSetMenuItemInfo.
 + *
 + */
 +static
 +BOOL
 +FASTCALL
 +MenuSetItemData(
 +  LPMENUITEMINFOW mii,
 +  UINT Flags,
 +  UINT_PTR IDNewItem,
 +  LPCWSTR NewItem,
 +  BOOL Unicode)
 +{
 +/*
 + * Let us assume MIIM_FTYPE is set and building a new menu item structure.
 + */
 +  if(Flags & MF_BITMAP)
 +  {
 +     mii->fMask |= MIIM_BITMAP;   /* Use the new way of seting hbmpItem.*/
 +     mii->hbmpItem = (HBITMAP) NewItem;
 +
 +     if (Flags & MF_HELP)
 +     {
 +         /* increase ident */
 +         mii->fType |= MF_HELP;
 +     }
 +  }
 +  else if(Flags & MF_OWNERDRAW)
 +  {
 +    mii->fType |= MFT_OWNERDRAW;
 +    mii->fMask |= MIIM_DATA;
 +    mii->dwItemData = (DWORD_PTR) NewItem;
 +  }
 +  else if (Flags & MF_SEPARATOR)
 +  {
 +    mii->fType |= MFT_SEPARATOR;
 +    if (!(Flags & (MF_GRAYED|MF_DISABLED)))
 +      Flags |= MF_GRAYED|MF_DISABLED;
 +  }
 +  else /* Default action MF_STRING. */
 +  {
 +    /* Item beginning with a backspace is a help item */
 +    if (NewItem != NULL)
 +    {
 +       if (Unicode)
 +       {
 +          if (*NewItem == '\b')
 +          {
 +             mii->fType |= MF_HELP;
 +             NewItem++;
 +          }
 +       }
 +       else
 +       {
 +          LPCSTR NewItemA = (LPCSTR) NewItem;
 +          if (*NewItemA == '\b')
 +          {
 +             mii->fType |= MF_HELP;
 +             NewItemA++;
 +             NewItem = (LPCWSTR) NewItemA;
 +          }
 +       }
 +
 +       if (Flags & MF_HELP)
 +         mii->fType |= MF_HELP;
 +       mii->fMask |= MIIM_STRING;
 +       mii->fType |= MFT_STRING; /* Zero */
 +       mii->dwTypeData = (LPWSTR)NewItem;
 +       if (Unicode)
 +         mii->cch = (NULL == NewItem ? 0 : strlenW(NewItem));
 +       else
 +         mii->cch = (NULL == NewItem ? 0 : strlen((LPCSTR)NewItem));
 +    }
 +    else
 +    {
 +      mii->fType |= MFT_SEPARATOR;
 +      if (!(Flags & (MF_GRAYED|MF_DISABLED)))
 +        Flags |= MF_GRAYED|MF_DISABLED;
 +    }
 +  }
 +
 +  if(Flags & MF_RIGHTJUSTIFY) /* Same as MF_HELP */
 +  {
 +    mii->fType |= MFT_RIGHTJUSTIFY;
 +  }
 +
 +  if(Flags & MF_MENUBREAK)
 +  {
 +    mii->fType |= MFT_MENUBREAK;
 +  }
 +  else if(Flags & MF_MENUBARBREAK)
 +  {
 +    mii->fType |= MFT_MENUBARBREAK;
 +  }
 +
 +  if(Flags & MF_GRAYED || Flags & MF_DISABLED)
 +  {
 +    if (Flags & MF_GRAYED)
 +      mii->fState |= MF_GRAYED;
 +
 +    if (Flags & MF_DISABLED)
 +      mii->fState |= MF_DISABLED;
 +
 +    mii->fMask |= MIIM_STATE;
 +  }
 +  else if (Flags & MF_HILITE)
 +  {
 +    mii->fState |= MF_HILITE;
 +    mii->fMask |= MIIM_STATE;
 +  }
 +  else /* default state */
 +  {
 +    mii->fState |= MFS_ENABLED;
 +    mii->fMask |= MIIM_STATE;
 +  }
 +
 +  if(Flags & MF_POPUP)
 +  {
 +    mii->fType |= MF_POPUP;
 +    mii->fMask |= MIIM_SUBMENU;
 +    mii->hSubMenu = (HMENU)IDNewItem;
 +  }
 +  else
 +  {
 +    mii->fMask |= MIIM_ID;
 +    mii->wID = (UINT)IDNewItem;
 +  }
 +  return TRUE;
 +}
 +
 +NTSTATUS WINAPI
 +User32CallLoadMenuFromKernel(PVOID Arguments, ULONG ArgumentLength)
 +{
 +  PLOADMENU_CALLBACK_ARGUMENTS Common;
 +  LRESULT Result;
 +
 +  Common = (PLOADMENU_CALLBACK_ARGUMENTS) Arguments;
 +
 +  Result = (LRESULT)LoadMenuW( Common->hModule,
 +                               IS_INTRESOURCE(Common->MenuName[0]) ?
 +                                  MAKEINTRESOURCE(Common->MenuName[0]) :
 +                                        (LPCWSTR)&Common->MenuName);
 +
 +  return ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS);
 +}
 +
 +
 +/* FUNCTIONS *****************************************************************/
 +
 +/*static BOOL
 +MenuIsStringItem(ULONG TypeData)
 +{
 +  return(MF_STRING == MENU_ITEM_TYPE(ItemInfo->fType));
 +}*/
 +
 +
 +/*
 + * @implemented
 + */
 +BOOL WINAPI
 +AppendMenuA(HMENU hMenu,
 +          UINT uFlags,
 +          UINT_PTR uIDNewItem,
 +          LPCSTR lpNewItem)
 +{
 +  return(InsertMenuA(hMenu, -1, uFlags | MF_BYPOSITION, uIDNewItem,
 +                   lpNewItem));
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +BOOL WINAPI
 +AppendMenuW(HMENU hMenu,
 +          UINT uFlags,
 +          UINT_PTR uIDNewItem,
 +          LPCWSTR lpNewItem)
 +{
 +  return(InsertMenuW(hMenu, -1, uFlags | MF_BYPOSITION, uIDNewItem,
 +                   lpNewItem));
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +DWORD WINAPI
 +CheckMenuItem(HMENU hmenu,
 +            UINT uIDCheckItem,
 +            UINT uCheck)
 +{
 +  return NtUserCheckMenuItem(hmenu, uIDCheckItem, uCheck);
 +}
 +
 +static
 +BOOL
 +MenuCheckMenuRadioItem(HMENU hMenu, UINT idFirst, UINT idLast, UINT idCheck, UINT uFlags, BOOL bCheck, PUINT pChecked, PUINT pUnchecked, PUINT pMenuChanged)
 +{
 +  UINT ItemCount, i;
 +  PROSMENUITEMINFO Items = NULL;
 +  UINT cChecked, cUnchecked;
 +  BOOL bRet = TRUE;
 +  //ROSMENUINFO mi;
 +
 +  if(idFirst > idLast)
 +      return FALSE;
 +
 +  ItemCount = GetMenuItemCount(hMenu);
 +
 +  //mi.cbSize = sizeof(ROSMENUINFO);
 +  //if(!NtUserMenuInfo(hmenu, &mi, FALSE)) return ret;
 +
 +
 +  if(MenuGetAllRosMenuItemInfo(hMenu, &Items) <= 0)
 +  {
 +    ERR("MenuGetAllRosMenuItemInfo failed\n");
 +    return FALSE;
 +  }
 +
 +  cChecked = cUnchecked = 0;
 +
 +  for (i = 0 ; i < ItemCount; i++)
 +  {
 +    BOOL check = FALSE;
 +    if (0 != (Items[i].fType & MF_MENUBARBREAK)) continue;
 +    if (0 != (Items[i].fType & MF_SEPARATOR)) continue;
 +
 +    if ((Items[i].fType & MF_POPUP) && (uFlags == MF_BYCOMMAND))
 +    {
 +      MenuCheckMenuRadioItem(Items[i].hSubMenu, idFirst, idLast, idCheck, uFlags, bCheck, pChecked, pUnchecked, pMenuChanged);
 +      continue;
 +    }
 +    if (uFlags & MF_BYPOSITION)
 +    {
 +      if (i < idFirst || i > idLast)
 +        continue;
 +
 +      if (i == idCheck)
 +      {
 +        cChecked++;
 +        check = TRUE;
 +      }
 +      else
 +      {
 +        cUnchecked++;
 +      }
 +    }
 +      else
 +      {
 +        if (Items[i].wID < idFirst || Items[i].wID > idLast)
 +          continue;
 +
 +        if (Items[i].wID == idCheck)
 +        {
 +          cChecked++;
 +          check = TRUE;
 +        }
 +        else
 +        {
 +          cUnchecked++;
 +        }
 +      }
 +
 +      if (!bCheck)
 +        continue;
 +
 +      Items[i].fMask = MIIM_STATE | MIIM_FTYPE;
 +      if (check)
 +      {
 +        Items[i].fType |= MFT_RADIOCHECK;
 +        Items[i].fState |= MFS_CHECKED;
 +      }
 +      else
 +      {
 +        Items[i].fState &= ~MFS_CHECKED;
 +      }
 +
 +      if(!MenuSetRosMenuItemInfo(hMenu, i ,&Items[i]))
 +      {
 +        ERR("MenuSetRosMenuItemInfo failed\n");
 +        bRet = FALSE;
 +        break;
 +      }
 +  }
 +  HeapFree(GetProcessHeap(), 0, Items);
 +
 +  *pChecked += cChecked;
 +  *pUnchecked += cUnchecked;
 +
 +  if (cChecked || cUnchecked)
 +    (*pMenuChanged)++;
 +
 +  return bRet;
 +}
 +
 +/*
 + * @implemented
 + */
 +BOOL WINAPI
 +CheckMenuRadioItem(HMENU hmenu,
 +                 UINT idFirst,
 +                 UINT idLast,
 +                 UINT idCheck,
 +                 UINT uFlags)
 +{
 +  UINT cChecked = 0;
 +  UINT cUnchecked = 0;
 +  UINT cMenuChanged = 0;
 +
 +  if (!MenuCheckMenuRadioItem(hmenu, idFirst, idLast, idCheck, uFlags, FALSE, &cChecked, &cUnchecked, &cMenuChanged))
 +    return FALSE;
 +
 +  if (cMenuChanged > 1)
 +    return FALSE;
 +
 +  cMenuChanged = 0;
 +  cChecked = 0;
 +  cUnchecked = 0;
 +
 +  if (!MenuCheckMenuRadioItem(hmenu, idFirst, idLast, idCheck, uFlags, TRUE, &cChecked, &cUnchecked, &cMenuChanged))
 +    return FALSE;
 +
 +  return (cChecked != 0);
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +HMENU WINAPI
 +CreateMenu(VOID)
 +{
 +  MenuLoadBitmaps();
 +  return (HMENU)NtUserCallNoParam(NOPARAM_ROUTINE_CREATEMENU);
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +HMENU WINAPI
 +CreatePopupMenu(VOID)
 +{
 +  MenuLoadBitmaps();
 +  return (HMENU)NtUserCallNoParam(NOPARAM_ROUTINE_CREATEMENUPOPUP);
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +BOOL WINAPI
 +DrawMenuBar(HWND hWnd)
 +{
 +//  return (BOOL)NtUserCallHwndLock(hWnd, HWNDLOCK_ROUTINE_DRAWMENUBAR);
 +  ROSMENUINFO MenuInfo;
 +  HMENU hMenu;
 +  hMenu = GetMenu(hWnd);
 +  if (!hMenu)
 +     return FALSE;
 +  MenuGetRosMenuInfo(&MenuInfo, hMenu);
 +  MenuInfo.Height = 0; // make sure to recalc size
 +  MenuSetRosMenuInfo(&MenuInfo);
 +  
 +  SetWindowPos( hWnd, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
 +                  SWP_NOZORDER | SWP_FRAMECHANGED );
 +  return TRUE;
 +}
 +
 +/*
 + * @implemented
 + */
 +BOOL WINAPI
 +EnableMenuItem(HMENU hMenu,
 +             UINT uIDEnableItem,
 +             UINT uEnable)
 +{
 +  return NtUserEnableMenuItem(hMenu, uIDEnableItem, uEnable);
 +}
 +
 +/*
 + * @implemented
 + */
 +BOOL WINAPI
 +EndMenu(VOID)
 +{
 +  GUITHREADINFO guii;
 +  guii.cbSize = sizeof(GUITHREADINFO);
 +  if(GetGUIThreadInfo(GetCurrentThreadId(), &guii) && guii.hwndMenuOwner)
 +  {
 +    if (!fEndMenu &&
 +         top_popup &&
 +         guii.hwndMenuOwner != top_popup )
 +    {
 +       ERR("Capture GUI pti hWnd does not match top_popup!\n");
 +    }
 +  }
 +
 +  /* if we are in the menu code, and it is active */
 +  if (!fEndMenu && top_popup)
 +  {
 +      /* terminate the menu handling code */
 +      fEndMenu = TRUE;
 +
 +      /* needs to be posted to wakeup the internal menu handler */
 +      /* which will now terminate the menu, in the event that */
 +      /* the main window was minimized, or lost focus, so we */
 +      /* don't end up with an orphaned menu */
 +      PostMessageW( top_popup, WM_CANCELMODE, 0, 0);
 +  }
 +  return TRUE;
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +HMENU WINAPI
 +GetMenu(HWND hWnd)
 +{
 +       PWND Wnd = ValidateHwnd(hWnd);
 +
 +       if (!Wnd)
 +               return NULL;
 +
 +       return UlongToHandle(Wnd->IDMenu);
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +LONG WINAPI
 +GetMenuCheckMarkDimensions(VOID)
 +{
 +  return(MAKELONG(GetSystemMetrics(SM_CXMENUCHECK),
 +                GetSystemMetrics(SM_CYMENUCHECK)));
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +UINT WINAPI
 +GetMenuDefaultItem(HMENU hMenu,
 +                 UINT fByPos,
 +                 UINT gmdiFlags)
 +{
 +  return NtUserGetMenuDefaultItem(hMenu, fByPos, gmdiFlags);
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +BOOL WINAPI
 +GetMenuInfo(HMENU hmenu,
 +          LPMENUINFO lpcmi)
 +{
 +  ROSMENUINFO mi;
 +  BOOL res = FALSE;
 +
 +  if(!lpcmi || (lpcmi->cbSize != sizeof(MENUINFO)))
 +    return FALSE;
 +
 +  RtlZeroMemory(&mi, sizeof(MENUINFO));
 +  mi.cbSize = sizeof(MENUINFO);
 +  mi.fMask = lpcmi->fMask;
 +
 +  res = NtUserMenuInfo(hmenu, &mi, FALSE);
 +
 +  memcpy(lpcmi, &mi, sizeof(MENUINFO));
 +  return res;
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +int WINAPI
 +GetMenuItemCount(HMENU Menu)
 +{
 +  ROSMENUINFO MenuInfo;
 +
 +  return MenuGetRosMenuInfo(&MenuInfo, Menu) ? MenuInfo.MenuItemCount : 0;
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +UINT WINAPI
 +GetMenuItemID(HMENU hMenu,
 +            int nPos)
 +{
 +  ROSMENUITEMINFO mii;
 +
 +  mii.cbSize = sizeof(MENUITEMINFOW);
 +  mii.fMask = MIIM_ID | MIIM_SUBMENU;
 +
 +  if (! NtUserMenuItemInfo(hMenu, nPos, MF_BYPOSITION, &mii, FALSE))
 +    {
 +      return -1;
 +    }
 +
 +  if (NULL != mii.hSubMenu)
 +    {
 +      return -1;
 +    }
 +  if (0 == mii.wID)
 +    {
 +      return -1;
 +    }
 +
 +  return mii.wID;
 +}
 +
 +
 +/*
 + * @implemented
 + */
 +BOOL WINAPI
 +GetMenuItemInfoA(
 +   HMENU Menu,
 +   UINT Item,
 +   BOOL ByPosition,
 +   LPMENUITEMINFOA mii)
 +{
 +   MENUITEMINFOW miiW;
 +   LPSTR AnsiBuffer;
 +   INT Count;
 +
 +   if (mii->cbSize != sizeof(MENUITEMINFOA) &&
 +       mii->cbSize != sizeof(MENUITEMINFOA) - sizeof(HBITMAP))
 +   {
 +      SetLastError(ERROR_INVALID_PARAMETER);
 +      return FALSE;
 +   }
 +
 +   if(!(mii->fMask & (MIIM_TYPE | MIIM_STRING)))
 +   {
 +      /* No text requested, just pass on */
 +      return NtUserMenuItemInfo(Menu, Item, ByPosition, (PROSMENUITEMINFO) mii, FALSE);
 +   }
 +
 +   AnsiBuffer = mii->dwTypeData;
 +   Count = miiW.cch = mii->cch;
 +   RtlCopyMemory(&miiW, mii, mii->cbSize);
 +   miiW.dwTypeData = 0;
 +
 +   if (AnsiBuffer)
 +   {
 +      miiW.dwTypeData = RtlAllocateHeap(GetProcessHeap(), 0,
 +                                        miiW.cch * sizeof(WCHAR));
 +      if (miiW.dwTypeData == NULL) return FALSE;
 +      miiW.dwTypeData[0] = 0;
 +   }
 +
 +   if (!NtUserMenuItemInfo(Menu, Item, ByPosition, (PROSMENUITEMINFO)&miiW, FALSE))
 +   {
 +      if (miiW.dwTypeData) RtlFreeHeap(GetProcessHeap(), 0, miiW.dwTypeData);
 +      return FALSE;
 +   }
 +
 +   RtlCopyMemory(mii, &miiW, miiW.cbSize);
 +
 +   if (!AnsiBuffer || !Count)
 +   {
 +      if (miiW.dwTypeData) RtlFreeHeap(GetProcessHeap(), 0, miiW.dwTypeData);
 +      mii->dwTypeData = AnsiBuffer;
 +      mii->cch = miiW.cch;
 +      return TRUE;
 +   }
 +
 +   if ((miiW.fMask & MIIM_STRING) || (IS_STRING_ITEM(miiW.fType)))
 +   {
 +      if (miiW.cch)
 +      {
 +         if (!WideCharToMultiByte(CP_ACP, 0, miiW.dwTypeData, miiW.cch, AnsiBuffer, mii->cch, NULL, NULL))
 +         {
 +            AnsiBuffer[0] = 0;
 +         }
 +         if (