mirror of
https://github.com/UzixLS/KernelEx.git
synced 2025-07-18 23:11:19 +03:00
import KernelEx-4.5-Beta1
This commit is contained in:
@ -1,3 +1,85 @@
|
||||
KernelEx v4.5 Beta 1 by Xeno86
|
||||
2010-01-18
|
||||
|
||||
disable named/rcdata resource types mirroring
|
||||
|
||||
changed obfuscator for non-negative PIDs
|
||||
|
||||
fix crash when a process is created with '.exe' renamed to '.dll'
|
||||
|
||||
added GDI anti-leaking code which forces NT destroying rules on font and bitmap objects.
|
||||
|
||||
implemented extended TLS (Thread Local Storage), extends limit of 80 to ~1100 slots
|
||||
|
||||
added Thunking Unicode Layer - set of user32 APIs
|
||||
which provides consistent Unicode window procedures conversion,
|
||||
allowing correct message conversion and mixture of window subclassing with NT-like rules.
|
||||
|
||||
revamped non-shared api library loading process
|
||||
|
||||
added jemalloc memory allocator, replacing standard Windows heap for applications
|
||||
|
||||
fix: LoadShfolderProc could crash if shfolder.dll was unloaded by the application
|
||||
|
||||
added USERENV library from Wine project
|
||||
|
||||
changed module configuration settings storage - single module can now have different configurations under different processes (better accuracy, overriding is supported, recursive inheritance is supported, speed gains)
|
||||
|
||||
change: Allow api library to be loaded even if some overridden modules aren't found (skips module tables)
|
||||
|
||||
shell folder fix - display CSIDL_COMMON_* folders in start menu
|
||||
|
||||
added support for environment variables in AppSettings database
|
||||
|
||||
added kexCOM - implementing IShellLinkW and IExtractIconW interfaces for CLSID_ShellLink which are missing from Windows 98 shell
|
||||
|
||||
Compatibility tab changes:
|
||||
* redesigned, added baloon tips
|
||||
* added option to disable configuration inheritance to child processes
|
||||
* added option to override module configuration with process'es configuration (debug only)
|
||||
* fixed COM implementation
|
||||
|
||||
changes into the installer:
|
||||
* enforce reboot after install/uninstall before subsequent installation,
|
||||
* copy kernel32.bak to temporary file during uninstall before reboot
|
||||
* forbid direct downgrades
|
||||
|
||||
API changes:
|
||||
|
||||
fix GlobalLock and GlobalUnlock to work properly with HeapAlloc pointers
|
||||
make CreateFile ignore unsupported FILE_SHARE_DELETE flag
|
||||
make GetDiskFreeSpace, GetDiskFreeSpaceEx not fail on certain file paths
|
||||
implemented USERENV.GetUserProfileDirectory, GetAllUsersProfileDirectory, GetProfilesDirectory
|
||||
added various winspool unicode (unicows) apis and stubs
|
||||
added EnumServicesStatusEx stubs
|
||||
fix CreateDIBSection to behave consistently with NT
|
||||
fix GetTempFileName to behave consistently with NT
|
||||
make ExtCreatePen not fail on PS_USERSTYLE pen style
|
||||
replaced MSLU GetObjectW (bug: MSLU always returns full object size regardless of buffer size passed) with custom implementation
|
||||
replaced MSLU RegEnumValueW with custom implementation
|
||||
added support for REG_EXPAND_SZ and REG_MULTI_SZ in RegQueryValueExW
|
||||
fixed RegQueryValueExW not handling return values properly
|
||||
fix: win9x doesn't allow MB_ERR_INVALID_CHARS parameter to be set for UTF-7 or UTF-8 codepages in MultiByteToWideChar and WideCharToMultiByte calls
|
||||
fix: RegisterWaitForSingleObject should test object state once and return immediatelly when dwMiliseconds is zero
|
||||
implemented GDI32.GetCharABCWidthsI, ADVAPI32.RtlGenRandom, KERNEL32.GetModuleHandleEx
|
||||
fixed uxtheme return addresses
|
||||
implemented theme metric functions
|
||||
fix WTSGetActiveConsoleSessionId should return 0 = local session instead 0xffffffff = no session
|
||||
implemented kernel32.DelayLoadFailureHook, QueueUserWorkItem, RegisterWaitForSingleObject, RegisterWaitForSingleObjectEx, UnregisterWait, UnregisterWaitEx, IsWow64Process, ProcessIdToSessionId, WTSGetActiveConsoleSessionId, IsWow64Process
|
||||
removed shlwapi.StrCmpLogicalW (which is available with IE6-updated shlwapi)
|
||||
implemented advapi32.DeleteAce
|
||||
added stubs for advapi32.NotifyBootConfigStatus, QueryWindows31FilesMigration, SynchronizeWindows31FilesAndWindowsNTRegistry
|
||||
changed advapi32.CreateWellKnownSid
|
||||
change: logfont* is optional in gdi32.EnumFontFamiliesEx on NT but not on 9x
|
||||
added stubs for kernel32.HeapSetInformation, GetProcessIoCounters, RtlCaptureStackBackTrace
|
||||
support events signalling in ReadFile & WriteFile overlapped apis
|
||||
fixed system bug in user32.GetNextDlgTabItem - system crashes trying to get next control in dialog to tab when there is only one control on dialog
|
||||
fixed GetDefaultPrinterW
|
||||
replaced SHGetFolderLocation Wine implementation with custom implementation
|
||||
fix: custom SHGetFolderLocation shouldn't be enabled for shell32 >= 5.0
|
||||
|
||||
---------------------------------------
|
||||
|
||||
KernelEx v4.0 Final 2 by Xeno86
|
||||
2009-08-20
|
||||
|
||||
|
@ -1,69 +0,0 @@
|
||||
KernelEx v4.0 Final 2 by Xeno86
|
||||
2009-08-20
|
||||
|
||||
Major changes:
|
||||
--------------
|
||||
* system won't try to load auxiliary libraries (PSAPI, MSIMG32, PDH, UXTHEME, WTSAPI32) when extensions are disabled
|
||||
|
||||
Fixed regressions:
|
||||
------------------
|
||||
* fixed ZoneAlarm not working properly
|
||||
* Firefox 3 couldn't be uninstalled if KernelEx was installed with extensions disabled
|
||||
* Foobar2000 v0.9.6.x installer was crashing
|
||||
|
||||
#################################################
|
||||
|
||||
KernelEx v4.0 Final by Xeno86
|
||||
2009-07-23
|
||||
|
||||
Now working on Windows 98/Me:
|
||||
-----------------------------
|
||||
* Flash 10 in Internet Explorer
|
||||
|
||||
Major changes:
|
||||
--------------
|
||||
* added option to installer to select between enabling KernelEx extensions for all applications and disabling them
|
||||
* added installation verifier
|
||||
* printer driver software no longer running in NT mode
|
||||
* file select dialogs in Flash applets and certain applications should work correctly now
|
||||
* improved RP9 compatibility
|
||||
* loading MSLU altered floating point unit flags and caused certain programs to crash
|
||||
* MSLU (Unicows.dll) is no longer loaded right on startup and should be seen referenced less often in system
|
||||
* Dependency Walker is no longer slow when profiling
|
||||
* startup speed improvements
|
||||
* stability improvements
|
||||
* tons of small changes
|
||||
|
||||
#################################################
|
||||
|
||||
KernelEx v4.0 RC 2 by Xeno86
|
||||
2009-03-21
|
||||
|
||||
Now working on Windows 98/Me:
|
||||
-----------------------------
|
||||
* The Chronicles of Riddick EFBB Demo
|
||||
* QEmu 0.9
|
||||
|
||||
Fixed regressions:
|
||||
------------------
|
||||
* fixed Adobe Acrobat Reader 7.0 not working with RC 1
|
||||
* .Net framework was broken in RC 1 now should work correctly
|
||||
* input issue in Firefox 3 affecting special characters
|
||||
* eMule couldn't complete downloads in RC 1, now fixed
|
||||
* transparency issue in Firefox 3
|
||||
* incompatibility with Norton Utilities
|
||||
|
||||
#################################################
|
||||
|
||||
KernelEx v4.0 RC 1 by Xeno86
|
||||
2009-03-10
|
||||
|
||||
Now working on Windows 98/Me:
|
||||
-----------------------------
|
||||
* Firefox 3.6 alpha
|
||||
* JDK 6 / JRE 6 works fine with the exception of Java applets which don't work (reason: missing proper named-pipe support in the system)
|
||||
* PDF-XChange Viewer now works
|
||||
|
||||
Fixed regressions:
|
||||
------------------
|
||||
* Sysinternals TCPView display fix
|
18
KernelEx.dsw
18
KernelEx.dsw
@ -23,9 +23,6 @@ Package=<5>
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name prep
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
@ -38,9 +35,6 @@ Package=<5>
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
Begin Project Dependency
|
||||
Project_Dep_Name prep
|
||||
End Project Dependency
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
@ -57,6 +51,18 @@ Package=<4>
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "kexCOM"=.\kexCOM\kexCOM.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "kexcontrol"=.\kexcontrol\kexcontrol.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
|
93
KernelEx.nsi
93
KernelEx.nsi
@ -1,4 +1,12 @@
|
||||
!define VERSION '4.0 Final 2'
|
||||
!define _VERSION '4.5 Beta 1'
|
||||
|
||||
!ifndef _DEBUG
|
||||
!define FLAVOUR 'Release'
|
||||
!define VERSION '${_VERSION}'
|
||||
!else
|
||||
!define FLAVOUR 'Debug'
|
||||
!define VERSION '${_VERSION} Debug'
|
||||
!endif
|
||||
|
||||
;--------------------------------
|
||||
;Includes
|
||||
@ -66,8 +74,6 @@
|
||||
LangString DESC_INSTALLING ${LANG_ENGLISH} "Installing"
|
||||
LangString DESC_DOWNLOADING1 ${LANG_ENGLISH} "Downloading"
|
||||
LangString DESC_DOWNLOADFAILED ${LANG_ENGLISH} "Download Failed:"
|
||||
LangString DESC_PRODUCT_TIMEOUT ${LANG_ENGLISH} "The installation of the $(DESC_SHORTPRODUCT) \
|
||||
has timed out."
|
||||
LangString ERROR_PRODUCT_INVALID_PATH ${LANG_ENGLISH} "The $(DESC_SHORTPRODUCT) Installation$\n\
|
||||
was not found in the following location:$\n"
|
||||
LangString ERROR_PRODUCT_FATAL ${LANG_ENGLISH} "A fatal error occurred during the installation$\n\
|
||||
@ -159,8 +165,7 @@ Section "MSLU" SECPRODUCT
|
||||
DetailPrint "$(DESC_INSTALLING) $(DESC_SHORTPRODUCT)..."
|
||||
Banner::show /NOUNLOAD "$(DESC_INSTALLING) $(DESC_SHORTPRODUCT)..."
|
||||
CreateDirectory "$INSTDIR\MSLU"
|
||||
nsExec::Exec '"$TEMP\unicows.exe" /t:$INSTDIR\MSLU'
|
||||
Pop $0
|
||||
ExecWait '"$TEMP\unicows.exe" /t:$INSTDIR\MSLU' $0
|
||||
Banner::destroy
|
||||
Delete "$TEMP\unicows.exe"
|
||||
|
||||
@ -169,18 +174,12 @@ Section "MSLU" SECPRODUCT
|
||||
; it will return "error"
|
||||
; If the process timed out it will return "timeout"
|
||||
; else it will return the return code from the executed process.
|
||||
StrCmp $0 "" lbl_NoError
|
||||
StrCmp $0 "" lbl_Error
|
||||
StrCmp $0 "0" lbl_NoError
|
||||
StrCmp $0 "error" lbl_Error
|
||||
StrCmp $0 "timeout" lbl_TimeOut
|
||||
; all others are fatal
|
||||
DetailPrint "$(ERROR_PRODUCT_FATAL)[$0]"
|
||||
Goto lbl_commonError
|
||||
|
||||
lbl_TimeOut:
|
||||
DetailPrint "$(DESC_PRODUCT_TIMEOUT)"
|
||||
Goto lbl_commonError
|
||||
|
||||
lbl_Error:
|
||||
DetailPrint "$(ERROR_PRODUCT_INVALID_PATH)"
|
||||
Goto lbl_commonError
|
||||
@ -200,14 +199,28 @@ SectionEnd
|
||||
Section "Install"
|
||||
|
||||
SetDetailsView show
|
||||
|
||||
ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\RunServicesOnce" "KexNeedsReboot"
|
||||
IfErrors +5
|
||||
DetailPrint "Detected unfinished previous installation."
|
||||
DetailPrint "You have to restart the system in order to complete it before you can proceed."
|
||||
MessageBox MB_ICONSTOP|MB_OK "You have to restart the system first."
|
||||
Abort
|
||||
|
||||
SetOutPath "$INSTDIR"
|
||||
|
||||
SetOverwrite on
|
||||
File setup\Release\setupkex.exe
|
||||
File setup\${FLAVOUR}\setupkex.exe
|
||||
SetOverwrite lastused
|
||||
|
||||
!ifdef _DEBUG
|
||||
nsExec::ExecToLog '"$INSTDIR\setupkex.exe" "$INSTDIR\kernel32.bak"'
|
||||
Pop $0
|
||||
!else
|
||||
ExecWait '"$INSTDIR\setupkex.exe" "$INSTDIR\kernel32.bak"' $0
|
||||
StrCmp $0 "" 0 +2
|
||||
StrCpy $0 "error"
|
||||
!endif
|
||||
DetailPrint " setup returned: $0"
|
||||
Delete "$INSTDIR\setupkex.exe"
|
||||
StrCmp $0 "0" +3
|
||||
@ -219,33 +232,40 @@ Section "Install"
|
||||
;UpdateDLL_Func params:
|
||||
;$R4 - target; $R5 - tempdir; $R6 - register?; $R7 - source
|
||||
GetTempFileName $0 "$INSTDIR"
|
||||
File /oname=$0 "Core\Release\KernelEx.dll"
|
||||
File /oname=$0 "Core\${FLAVOUR}\KernelEx.dll"
|
||||
StrCpy $R4 "$INSTDIR\KernelEx.dll"
|
||||
StrCpy $R6 "0"
|
||||
StrCpy $R7 $0
|
||||
Call UpgradeDLL_Func
|
||||
|
||||
GetTempFileName $0 "$INSTDIR"
|
||||
File /oname=$0 "apilibs\kexbases\Release\kexbases.dll"
|
||||
File /oname=$0 "apilibs\kexbases\${FLAVOUR}\kexbases.dll"
|
||||
StrCpy $R4 "$INSTDIR\kexbases.dll"
|
||||
StrCpy $R6 "0"
|
||||
StrCpy $R7 $0
|
||||
Call UpgradeDLL_Func
|
||||
|
||||
GetTempFileName $0 "$INSTDIR"
|
||||
File /oname=$0 "apilibs\kexbasen\Release\kexbasen.dll"
|
||||
File /oname=$0 "apilibs\kexbasen\${FLAVOUR}\kexbasen.dll"
|
||||
StrCpy $R4 "$INSTDIR\kexbasen.dll"
|
||||
StrCpy $R6 "0"
|
||||
StrCpy $R7 $0
|
||||
Call UpgradeDLL_Func
|
||||
|
||||
GetTempFileName $0 "$INSTDIR"
|
||||
File /oname=$0 "sheet\Release\sheet.dll"
|
||||
File /oname=$0 "sheet\${FLAVOUR}\sheet.dll"
|
||||
StrCpy $R4 "$INSTDIR\sheet.dll"
|
||||
StrCpy $R6 "1"
|
||||
StrCpy $R7 $0
|
||||
Call UpgradeDLL_Func
|
||||
|
||||
GetTempFileName $0 "$INSTDIR"
|
||||
File /oname=$0 "kexCOM\${FLAVOUR}\kexCOM.dll"
|
||||
StrCpy $R4 "$INSTDIR\kexCOM.dll"
|
||||
StrCpy $R6 "1"
|
||||
StrCpy $R7 $0
|
||||
Call UpgradeDLL_Func
|
||||
|
||||
SetOverwrite on
|
||||
|
||||
File apilibs\core.ini
|
||||
@ -287,6 +307,13 @@ Section "Install"
|
||||
WriteRegStr HKLM "Software\KernelEx\KnownDLLs" \
|
||||
"WTSAPI32" "WTSAPI32.DLL"
|
||||
|
||||
GetTempFileName $0 "$INSTDIR"
|
||||
File /oname=$0 auxiliary\userenv.dll
|
||||
Delete "$INSTDIR\userenv.dll"
|
||||
Rename /REBOOTOK $0 "$INSTDIR\userenv.dll"
|
||||
WriteRegStr HKLM "Software\KernelEx\KnownDLLs" \
|
||||
"USERENV" "USERENV.DLL"
|
||||
|
||||
SetOverwrite lastused
|
||||
|
||||
ExecWait '"$WINDIR\regedit.exe" /s "$INSTDIR\settings.reg"'
|
||||
@ -306,7 +333,7 @@ Section "Install"
|
||||
|
||||
;Write verifier
|
||||
SetOverWrite on
|
||||
File verify\Release\verify.exe
|
||||
File verify\${FLAVOUR}\verify.exe
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Run" \
|
||||
"KexVerify" "$INSTDIR\verify.exe"
|
||||
SetOverwrite lastused
|
||||
@ -314,6 +341,7 @@ Section "Install"
|
||||
;Create uninstaller
|
||||
WriteUninstaller "$INSTDIR\Uninstall.exe"
|
||||
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\RunServicesOnce" "KexNeedsReboot" ""
|
||||
SetRebootFlag true
|
||||
|
||||
SectionEnd
|
||||
@ -325,20 +353,28 @@ Section "Uninstall"
|
||||
|
||||
SetDetailsView show
|
||||
|
||||
MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "$(DESC_SETTINGS_PRESERVE)" IDYES +2 IDNO 0
|
||||
DeleteRegKey HKLM "Software\KernelEx"
|
||||
|
||||
DeleteRegKey HKLM "System\CurrentControlSet\Control\MPRServices\KernelEx"
|
||||
DeleteRegKey /ifempty HKLM "System\CurrentControlSet\Control\MPRServices"
|
||||
ReadRegStr $0 HKLM "Software\Microsoft\Windows\CurrentVersion\RunServicesOnce" "KexNeedsReboot"
|
||||
IfErrors +5
|
||||
DetailPrint "Detected unfinished previous installation."
|
||||
DetailPrint "You have to restart the system in order to complete it before you can proceed."
|
||||
MessageBox MB_ICONSTOP|MB_OK "You have to restart the system first."
|
||||
Abort
|
||||
|
||||
;Files to uninstall
|
||||
Rename /REBOOTOK "$INSTDIR\kernel32.bak" "$SYSDIR\kernel32.dll"
|
||||
IfFileExists "$INSTDIR\kernel32.bak" 0 +5
|
||||
GetTempFileName $0 "$SYSDIR"
|
||||
Delete $0
|
||||
Rename "$INSTDIR\kernel32.bak" $0
|
||||
Rename /REBOOTOK $0 "$SYSDIR\kernel32.dll"
|
||||
|
||||
Delete /REBOOTOK "$INSTDIR\KernelEx.dll"
|
||||
Delete /REBOOTOK "$INSTDIR\kexbases.dll"
|
||||
Delete /REBOOTOK "$INSTDIR\kexbasen.dll"
|
||||
Delete "$INSTDIR\core.ini"
|
||||
UnRegDLL "$INSTDIR\sheet.dll"
|
||||
Delete /REBOOTOK "$INSTDIR\sheet.dll"
|
||||
UnRegDLL "$INSTDIR\kexCOM.dll"
|
||||
Delete /REBOOTOK "$INSTDIR\kexCOM.dll"
|
||||
Delete "$INSTDIR\license.txt"
|
||||
|
||||
Delete /REBOOTOK "$INSTDIR\msimg32.dll"
|
||||
@ -351,6 +387,8 @@ Section "Uninstall"
|
||||
DeleteRegValue HKLM "Software\KernelEx\KnownDLLs" "UXTHEME"
|
||||
Delete /REBOOTOK "$INSTDIR\wtsapi32.dll"
|
||||
DeleteRegValue HKLM "Software\KernelEx\KnownDLLs" "WTSAPI32"
|
||||
Delete /REBOOTOK "$INSTDIR\userenv.dll"
|
||||
DeleteRegValue HKLM "Software\KernelEx\KnownDLLs" "USERENV"
|
||||
|
||||
Delete "$INSTDIR\verify.exe"
|
||||
DeleteRegValue HKLM "Software\Microsoft\Windows\CurrentVersion\Run" "KexVerify"
|
||||
@ -360,8 +398,15 @@ Section "Uninstall"
|
||||
RMDir /r "$INSTDIR\MSLU"
|
||||
WriteINIStr $WINDIR\wininit.ini Rename DIRNUL $INSTDIR
|
||||
|
||||
MessageBox MB_ICONQUESTION|MB_YESNO|MB_DEFBUTTON2 "$(DESC_SETTINGS_PRESERVE)" IDYES +2 IDNO 0
|
||||
DeleteRegKey HKLM "Software\KernelEx"
|
||||
|
||||
DeleteRegKey HKLM "System\CurrentControlSet\Control\MPRServices\KernelEx"
|
||||
DeleteRegKey /ifempty HKLM "System\CurrentControlSet\Control\MPRServices"
|
||||
|
||||
DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\KernelEx"
|
||||
|
||||
WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\RunServicesOnce" "KexNeedsReboot" ""
|
||||
SetRebootFlag true
|
||||
|
||||
SectionEnd
|
||||
|
123
NEWS.txt
Executable file
123
NEWS.txt
Executable file
@ -0,0 +1,123 @@
|
||||
KernelEx v4.5 Beta 1 by Xeno86
|
||||
2010-01-18
|
||||
|
||||
What's new:
|
||||
----------------------------------
|
||||
* Noticeably improved speed of applications which make extensive use of memory.
|
||||
This was made possible by introducing new memory allocator originating from FreeBSD - jemalloc.
|
||||
It improves heap memory allocation/free speed and reduces virtual memory fragmentation.
|
||||
* Improved compatibility with Unicode applications by implementing new windowing layer
|
||||
which provides NT-consistent way to work with Unicode window procedures.
|
||||
* Extended TLS slot limitation from 80 to 1000+, for some heavy apps.
|
||||
* Lifted PE loader named resource limitation, allowing named resource-heavy libraries to load.
|
||||
* Changed kernel obfuscator to produce positive object (process, thread) IDs in order to improve compatibility.
|
||||
* Introduced kexCOM - new library to take care of missing COM interfaces. Fixes creating shell shortcuts in newer installers.
|
||||
* GDI object destroying rules adjusted in order to fix certain resource leaks or unstability with Flash and other apps.
|
||||
* Implemented certain userenv, unicode winspool, thread pool functions.
|
||||
* Lot of API fixes and stubs.
|
||||
* Improved Compatibility tab.
|
||||
* Various architecture improvements.
|
||||
* Fixed uninstall kernel32.bak not restoring reliably issue.
|
||||
|
||||
Apps now working / fixed:
|
||||
-------------------------
|
||||
* .NET Framework 2 (fixed install/uninstall and apps)
|
||||
* AbiWord 2.8 (usable, minor problems)
|
||||
* Adobe Flash 10.1 beta
|
||||
* Adobe Acrobat Reader 9 (very unstable)
|
||||
* Adobe ImageReady CS2 (no Photoshop yet)
|
||||
* Arora (WebKit Internet Browser)
|
||||
* FastStone Image Viewer (fixed plugin crash)
|
||||
* Foxit Reader 3.1
|
||||
* ICQ 6.5 / ICQLite
|
||||
* InkScape (usable)
|
||||
* GIMP 2.6 (usable, fixed brush trace)
|
||||
* Half-Life 2 Episode One/Two
|
||||
* Miranda IM 0.8.x Unicode
|
||||
* Mozilla Thunderbird 3 (fixed out of space errors)
|
||||
* Nero DiscSpeed 4
|
||||
* QtCreator 1.2.1
|
||||
* SoftMaker Office 2008 (fixed input bugs)
|
||||
* WinAmp 5.5x (fixed ML crash, charset problems)
|
||||
* X-Moto
|
||||
|
||||
|
||||
Notes:
|
||||
------
|
||||
* This release is beta quality in order to test several major changes in KernelEx.
|
||||
Please test the apps which were working before. Compare the performance and memory usage of any heavy apps you use.
|
||||
Pay attention to possible national language input problems.
|
||||
* If you want to downgrade to Final 2, you have to uninstall this beta first.
|
||||
* Enjoy this great release. win9x 4ever.
|
||||
|
||||
#################################################
|
||||
|
||||
KernelEx v4.0 Final 2 by Xeno86
|
||||
2009-08-20
|
||||
|
||||
Major changes:
|
||||
--------------
|
||||
* system won't try to load auxiliary libraries (PSAPI, MSIMG32, PDH, UXTHEME, WTSAPI32) when extensions are disabled
|
||||
|
||||
Fixed regressions:
|
||||
------------------
|
||||
* fixed ZoneAlarm not working properly
|
||||
* Firefox 3 couldn't be uninstalled if KernelEx was installed with extensions disabled
|
||||
* Foobar2000 v0.9.6.x installer was crashing
|
||||
|
||||
#################################################
|
||||
|
||||
KernelEx v4.0 Final by Xeno86
|
||||
2009-07-23
|
||||
|
||||
Now working on Windows 98/Me:
|
||||
-----------------------------
|
||||
* Flash 10 in Internet Explorer
|
||||
|
||||
Major changes:
|
||||
--------------
|
||||
* added option to installer to select between enabling KernelEx extensions for all applications and disabling them
|
||||
* added installation verifier
|
||||
* printer driver software no longer running in NT mode
|
||||
* file select dialogs in Flash applets and certain applications should work correctly now
|
||||
* improved RP9 compatibility
|
||||
* loading MSLU altered floating point unit flags and caused certain programs to crash
|
||||
* MSLU (Unicows.dll) is no longer loaded right on startup and should be seen referenced less often in system
|
||||
* Dependency Walker is no longer slow when profiling
|
||||
* startup speed improvements
|
||||
* stability improvements
|
||||
* tons of small changes
|
||||
|
||||
#################################################
|
||||
|
||||
KernelEx v4.0 RC 2 by Xeno86
|
||||
2009-03-21
|
||||
|
||||
Now working on Windows 98/Me:
|
||||
-----------------------------
|
||||
* The Chronicles of Riddick EFBB Demo
|
||||
* QEmu 0.9
|
||||
|
||||
Fixed regressions:
|
||||
------------------
|
||||
* fixed Adobe Acrobat Reader 7.0 not working with RC 1
|
||||
* .Net framework was broken in RC 1 now should work correctly
|
||||
* input issue in Firefox 3 affecting special characters
|
||||
* eMule couldn't complete downloads in RC 1, now fixed
|
||||
* transparency issue in Firefox 3
|
||||
* incompatibility with Norton Utilities
|
||||
|
||||
#################################################
|
||||
|
||||
KernelEx v4.0 RC 1 by Xeno86
|
||||
2009-03-10
|
||||
|
||||
Now working on Windows 98/Me:
|
||||
-----------------------------
|
||||
* Firefox 3.6 alpha
|
||||
* JDK 6 / JRE 6 works fine with the exception of Java applets which don't work (reason: missing proper named-pipe support in the system)
|
||||
* PDF-XChange Viewer now works
|
||||
|
||||
Fixed regressions:
|
||||
------------------
|
||||
* Sysinternals TCPView display fix
|
0
apilibs/CORE.INI
Normal file → Executable file
0
apilibs/CORE.INI
Normal file → Executable file
1
apilibs/kexbasen/advapi32/_advapi32_apilist.c
Normal file → Executable file
1
apilibs/kexbasen/advapi32/_advapi32_apilist.c
Normal file → Executable file
@ -40,7 +40,6 @@ static const apilib_named_api advapi32_named_apis[] =
|
||||
DECL_API("RegDeleteValueW", RegDeleteValueW_fwd),
|
||||
DECL_API("RegEnumKeyExW", RegEnumKeyExW_fwd),
|
||||
DECL_API("RegEnumKeyW", RegEnumKeyW_fwd),
|
||||
DECL_API("RegEnumValueW", RegEnumValueW_fwd),
|
||||
DECL_API("RegLoadKeyW", RegLoadKeyW_fwd),
|
||||
DECL_API("RegOpenKeyExW", RegOpenKeyExW_fwd),
|
||||
DECL_API("RegOpenKeyW", RegOpenKeyW_fwd),
|
||||
|
1
apilibs/kexbasen/advapi32/_advapi32_apilist.h
Normal file → Executable file
1
apilibs/kexbasen/advapi32/_advapi32_apilist.h
Normal file → Executable file
@ -37,7 +37,6 @@ FWDPROC RegDeleteKeyW_fwd;
|
||||
FWDPROC RegDeleteValueW_fwd;
|
||||
FWDPROC RegEnumKeyExW_fwd;
|
||||
FWDPROC RegEnumKeyW_fwd;
|
||||
FWDPROC RegEnumValueW_fwd;
|
||||
FWDPROC RegLoadKeyW_fwd;
|
||||
FWDPROC RegOpenKeyExW_fwd;
|
||||
FWDPROC RegOpenKeyW_fwd;
|
||||
|
1
apilibs/kexbasen/advapi32/uniadvapi32.c
Normal file → Executable file
1
apilibs/kexbasen/advapi32/uniadvapi32.c
Normal file → Executable file
@ -30,7 +30,6 @@ FORWARD_TO_UNICOWS(RegDeleteKeyW);
|
||||
FORWARD_TO_UNICOWS(RegDeleteValueW);
|
||||
FORWARD_TO_UNICOWS(RegEnumKeyExW);
|
||||
FORWARD_TO_UNICOWS(RegEnumKeyW);
|
||||
FORWARD_TO_UNICOWS(RegEnumValueW);
|
||||
FORWARD_TO_UNICOWS(RegLoadKeyW);
|
||||
FORWARD_TO_UNICOWS(RegOpenKeyExW);
|
||||
FORWARD_TO_UNICOWS(RegOpenKeyW);
|
||||
|
0
apilibs/kexbasen/comdlg32/_comdlg32_apilist.c
Normal file → Executable file
0
apilibs/kexbasen/comdlg32/_comdlg32_apilist.c
Normal file → Executable file
0
apilibs/kexbasen/comdlg32/_comdlg32_apilist.h
Normal file → Executable file
0
apilibs/kexbasen/comdlg32/_comdlg32_apilist.h
Normal file → Executable file
0
apilibs/kexbasen/comdlg32/openfilename_fix.c
Normal file → Executable file
0
apilibs/kexbasen/comdlg32/openfilename_fix.c
Normal file → Executable file
0
apilibs/kexbasen/comdlg32/unicomdlg32.c
Normal file → Executable file
0
apilibs/kexbasen/comdlg32/unicomdlg32.c
Normal file → Executable file
1
apilibs/kexbasen/common.c
Normal file → Executable file
1
apilibs/kexbasen/common.c
Normal file → Executable file
@ -54,6 +54,5 @@ char* file_fixWprefix(char* in)
|
||||
void fatal_error(const char* msg)
|
||||
{
|
||||
MessageBox(NULL, msg, "KernelEx error", MB_OK | MB_ICONERROR);
|
||||
#pragma message("place DBGBREAK here!!!!")
|
||||
ExitProcess(1);
|
||||
}
|
||||
|
13
apilibs/kexbasen/common.h
Normal file → Executable file
13
apilibs/kexbasen/common.h
Normal file → Executable file
@ -25,6 +25,10 @@
|
||||
#include <windows.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef int __stdcall STUB(void);
|
||||
typedef int __stdcall FWDPROC(void);
|
||||
|
||||
@ -34,12 +38,15 @@ int WINAPI CommonUnimpStub(void);
|
||||
char* file_fixWprefix(char* in);
|
||||
void fatal_error(const char* msg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define UNIMPL_FUNC(name,params) \
|
||||
__asm__( ".text\n" \
|
||||
".globl _" #name "_stub@0\n" \
|
||||
"_" #name "_new@0:\n\t" \
|
||||
"_" #name "_stub@0:\n\t" \
|
||||
"xor %eax, %eax\n\t" \
|
||||
"movb $" #params ", %cl\n\t" \
|
||||
"jmp _CommonUnimpStub@0\n\t" \
|
||||
@ -61,7 +68,7 @@ void fatal_error(const char* msg);
|
||||
const WCHAR* p; \
|
||||
int c; \
|
||||
for (p = str##W ; *p ; p++); \
|
||||
c = (int) p - (int) str##W; \
|
||||
c = p - str##W + 1; \
|
||||
c *= acp_mcs; \
|
||||
str##A = (char*) alloca(c); \
|
||||
WtoA(str, c)
|
||||
@ -94,7 +101,7 @@ void fatal_error(const char* msg);
|
||||
const WCHAR* p; \
|
||||
int c; \
|
||||
for (p = str##W ; *p ; p++); \
|
||||
c = (int) p - (int) str##W; \
|
||||
c = p - str##W + 1; \
|
||||
c *= acp_mcs; \
|
||||
str##A = (char*) alloca(c); \
|
||||
file_WtoA(str, c); \
|
||||
|
2
apilibs/kexbasen/dirlist
Normal file → Executable file
2
apilibs/kexbasen/dirlist
Normal file → Executable file
@ -6,4 +6,4 @@ comdlg32
|
||||
shell32
|
||||
rpcrt4
|
||||
winspool
|
||||
shlwapi
|
||||
shfolder
|
||||
|
40
apilibs/kexbasen/gdi32/UberGDI.c
Normal file → Executable file
40
apilibs/kexbasen/gdi32/UberGDI.c
Normal file → Executable file
@ -202,6 +202,46 @@ BOOL WINAPI GetCharWidthI_new(
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
//NOTE: usp10 is probing for that function, don't forget to exclude it
|
||||
|
||||
/* MAKE_EXPORT GetCharABCWidthsI_new=GetCharABCWidthsI */
|
||||
BOOL WINAPI GetCharABCWidthsI_new(
|
||||
HDC hdc, // handle to DC
|
||||
UINT giFirst, // first glyph index in range
|
||||
UINT cgi, // count of glyph indices in range
|
||||
LPWORD pgi, // array of glyph indices
|
||||
LPABC lpabc // array of character widths
|
||||
)
|
||||
{
|
||||
SCRIPT_CACHE cache = 0;
|
||||
WORD glyph;
|
||||
|
||||
if ( !hdc || !lpabc || cgi<=0)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
if ( !pgi ) //cgi glyphs starting giFirst
|
||||
{
|
||||
for ( glyph = giFirst; glyph < giFirst+cgi; glyph++)
|
||||
{
|
||||
ScriptGetGlyphABCWidth(hdc,&cache,glyph,lpabc);
|
||||
lpabc++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( glyph = 0; glyph < cgi; glyph++)
|
||||
{
|
||||
ScriptGetGlyphABCWidth(hdc,&cache,*pgi,lpabc);
|
||||
pgi++;
|
||||
lpabc++;
|
||||
}
|
||||
}
|
||||
ScriptFreeCache(&cache);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT GetGlyphOutlineW_new=GetGlyphOutlineW */
|
||||
DWORD WINAPI GetGlyphOutlineW_new(
|
||||
HDC hdc, // handle to DC
|
||||
|
2
apilibs/kexbasen/gdi32/_gdi32_apilist.c
Normal file → Executable file
2
apilibs/kexbasen/gdi32/_gdi32_apilist.c
Normal file → Executable file
@ -43,6 +43,7 @@ static const apilib_named_api gdi32_named_apis[] =
|
||||
DECL_API("CreateScalableFontResourceW", CreateScalableFontResourceW_fwd),
|
||||
DECL_API("EnumFontsW", EnumFontsW_fwd),
|
||||
DECL_API("EnumICMProfilesW", EnumICMProfilesW_fwd),
|
||||
DECL_API("GetCharABCWidthsI", GetCharABCWidthsI_new),
|
||||
DECL_API("GetCharABCWidthsW", GetCharABCWidthsW_fwd),
|
||||
DECL_API("GetCharWidthI", GetCharWidthI_new),
|
||||
DECL_API("GetCharacterPlacementW", GetCharacterPlacementW_fwd),
|
||||
@ -55,7 +56,6 @@ static const apilib_named_api gdi32_named_apis[] =
|
||||
DECL_API("GetKerningPairsW", GetKerningPairsW_fwd),
|
||||
DECL_API("GetLogColorSpaceW", GetLogColorSpaceW_fwd),
|
||||
DECL_API("GetMetaFileW", GetMetaFileW_fwd),
|
||||
DECL_API("GetObjectW", GetObjectW_fwd),
|
||||
DECL_API("GetOutlineTextMetricsW", GetOutlineTextMetricsW_fwd),
|
||||
DECL_API("GetTextExtentExPointI", GetTextExtentExPointI_new),
|
||||
DECL_API("GetTextExtentExPointW", GetTextExtentExPointW_fwd),
|
||||
|
2
apilibs/kexbasen/gdi32/_gdi32_apilist.h
Normal file → Executable file
2
apilibs/kexbasen/gdi32/_gdi32_apilist.h
Normal file → Executable file
@ -33,6 +33,7 @@ int WINAPI GetGlyphIndicesA_new(HDC hdc, LPCSTR lpstr, int c, LPWORD pgi, DWORD
|
||||
BOOL WINAPI GetTextExtentExPointI_new(HDC hdc, LPWORD pgiIn, int cgi, int nMaxExtent, LPINT lpnFit, LPINT alpDx, LPSIZE lpSize);
|
||||
BOOL WINAPI GetTextExtentPointI_new(HDC hdc, LPWORD pgiIn, int cgi, LPSIZE lpSize);
|
||||
BOOL WINAPI GetCharWidthI_new(HDC hdc, UINT giFirst, UINT cgi, WORD* pgi, INT* lpBuffer);
|
||||
BOOL WINAPI GetCharABCWidthsI_new(HDC hdc, UINT giFirst, UINT cgi, LPWORD pgi, LPABC lpabc);
|
||||
DWORD WINAPI GetGlyphOutlineW_new(HDC hdc, UINT uChar, UINT uFormat, LPGLYPHMETRICS lpgm, DWORD cbBuffer, LPVOID lpvBuffer, CONST MAT2 *lpmat2);
|
||||
FWDPROC CopyEnhMetaFileW_fwd;
|
||||
FWDPROC CopyMetaFileW_fwd;
|
||||
@ -54,7 +55,6 @@ FWDPROC GetICMProfileW_fwd;
|
||||
FWDPROC GetKerningPairsW_fwd;
|
||||
FWDPROC GetLogColorSpaceW_fwd;
|
||||
FWDPROC GetMetaFileW_fwd;
|
||||
FWDPROC GetObjectW_fwd;
|
||||
FWDPROC GetOutlineTextMetricsW_fwd;
|
||||
FWDPROC GetTextExtentExPointW_fwd;
|
||||
FWDPROC GetTextFaceW_fwd;
|
||||
|
1
apilibs/kexbasen/gdi32/unigdi32.c
Normal file → Executable file
1
apilibs/kexbasen/gdi32/unigdi32.c
Normal file → Executable file
@ -41,7 +41,6 @@ FORWARD_TO_UNICOWS(GetICMProfileW);
|
||||
FORWARD_TO_UNICOWS(GetKerningPairsW);
|
||||
FORWARD_TO_UNICOWS(GetLogColorSpaceW);
|
||||
FORWARD_TO_UNICOWS(GetMetaFileW);
|
||||
FORWARD_TO_UNICOWS(GetObjectW);
|
||||
FORWARD_TO_UNICOWS(GetOutlineTextMetricsW);
|
||||
FORWARD_TO_UNICOWS(GetTextExtentExPointW);
|
||||
FORWARD_TO_UNICOWS(GetTextFaceW);
|
||||
|
63
apilibs/kexbasen/kernel32/DelayLoadFailureHook.c
Executable file
63
apilibs/kexbasen/kernel32/DelayLoadFailureHook.c
Executable file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* KernelEx
|
||||
*
|
||||
* Copyright (C) 2009, Tihiy
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
* KernelEx is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* KernelEx is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
DWORD unknown[3];
|
||||
LPSTR dllName;
|
||||
DWORD unknown2;
|
||||
LPSTR procName;
|
||||
} SHLWAPI_DELAYLOAD, *PSHLWAPI_DELAYLOAD;
|
||||
|
||||
/*
|
||||
* shlwapi has half of whole Windows API reimplemented
|
||||
* and DelayLoadFailureHook in some retarded wrapper export
|
||||
*/
|
||||
|
||||
static HMODULE hShlwapi;
|
||||
typedef FARPROC (WINAPI* DLFH) (DWORD, PSHLWAPI_DELAYLOAD);
|
||||
|
||||
/* MAKE_EXPORT DelayLoadFailureHook_new=DelayLoadFailureHook */
|
||||
FARPROC WINAPI DelayLoadFailureHook_new(
|
||||
LPSTR pszDllName,
|
||||
LPSTR pszProcName
|
||||
)
|
||||
{
|
||||
SHLWAPI_DELAYLOAD param;
|
||||
|
||||
if (!hShlwapi)
|
||||
{
|
||||
hShlwapi = GetModuleHandle("shlwapi.dll");
|
||||
if (!hShlwapi)
|
||||
hShlwapi = LoadLibrary("shlwapi.dll");
|
||||
}
|
||||
|
||||
DLFH ShlwapiDelayLoad = (DLFH) GetProcAddress(hShlwapi,"DelayLoadFailureHook");
|
||||
if (!ShlwapiDelayLoad)
|
||||
return NULL;
|
||||
|
||||
param.dllName = pszDllName;
|
||||
param.procName = pszProcName;
|
||||
|
||||
return ShlwapiDelayLoad(4,¶m);
|
||||
}
|
238
apilibs/kexbasen/kernel32/ThreadPool.c
Executable file
238
apilibs/kexbasen/kernel32/ThreadPool.c
Executable file
@ -0,0 +1,238 @@
|
||||
/*
|
||||
* KernelEx
|
||||
* Copyright (C) 2009, Tihiy
|
||||
* Copyright (c) 2006 Robert Shearman (WINE Project)
|
||||
*
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
* KernelEx is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* KernelEx is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include "shlord.h"
|
||||
|
||||
/*
|
||||
* The following functions are implemented:
|
||||
* QueueUserWorkItem (with SHLWAPI.SHQueueUserWorkItem)
|
||||
* RegisterWaitForSingleObject
|
||||
* RegisterWaitForSingleObjectEx
|
||||
* UnregisterWait
|
||||
* UnregisterWaitEx
|
||||
* all functions could be implemented with shlwapi,
|
||||
* but they don't support async de-registration and most flags
|
||||
* Also, Wine functions can cause problems in cases like
|
||||
* when second unregister is called, or handle is reused...
|
||||
* But Windows XP also fails hard in such cases.
|
||||
*/
|
||||
|
||||
#define TPS_EXECUTEIO 0x00000001
|
||||
#define TPS_LONGEXECTIME 0x00000008
|
||||
|
||||
typedef BOOL (WINAPI* SHQueueUserWorkItem_API) (LPTHREAD_START_ROUTINE pfnCallback,
|
||||
LPVOID pContext,
|
||||
LONG lPriority,
|
||||
PDWORD dwTag,
|
||||
PDWORD * pdwId,
|
||||
LPCSTR pszModule,
|
||||
DWORD dwFlags);
|
||||
|
||||
static SHQueueUserWorkItem_API SHQueueUserWorkItem;
|
||||
|
||||
|
||||
/* MAKE_EXPORT QueueUserWorkItem_new=QueueUserWorkItem */
|
||||
BOOL WINAPI QueueUserWorkItem_new( LPTHREAD_START_ROUTINE Function, PVOID Context, ULONG Flags)
|
||||
{
|
||||
if (!SHQueueUserWorkItem)
|
||||
SHQueueUserWorkItem = (SHQueueUserWorkItem_API)GetShlwapiProc(260);
|
||||
|
||||
DWORD dwFlags = 0;
|
||||
if (Flags & WT_EXECUTEINIOTHREAD) dwFlags |= TPS_EXECUTEIO;
|
||||
if (Flags & WT_EXECUTELONGFUNCTION) dwFlags |= TPS_LONGEXECTIME;
|
||||
|
||||
return SHQueueUserWorkItem( Function, Context, 0, NULL, NULL, NULL, dwFlags );
|
||||
}
|
||||
|
||||
//registerwait routines
|
||||
typedef struct
|
||||
{
|
||||
HANDLE Object;
|
||||
HANDLE CancelEvent;
|
||||
WAITORTIMERCALLBACK Callback;
|
||||
PVOID Context;
|
||||
ULONG Milliseconds;
|
||||
ULONG Flags;
|
||||
HANDLE CompletionEvent;
|
||||
LONG DeleteCount;
|
||||
BOOLEAN CallbackInProgress;
|
||||
} wait_work_item_struct, *wait_work_item_ptr;
|
||||
|
||||
static void delete_wait_work_item(wait_work_item_ptr wait_work_item)
|
||||
{
|
||||
CloseHandle( wait_work_item->CancelEvent );
|
||||
wait_work_item->CancelEvent = 0; //in case someone tries to work on deleted handle
|
||||
HeapFree( GetProcessHeap(), 0, wait_work_item );
|
||||
}
|
||||
|
||||
static DWORD CALLBACK wait_thread_proc(LPVOID Arg)
|
||||
{
|
||||
wait_work_item_ptr wait_work_item = (wait_work_item_ptr)Arg;
|
||||
BOOL alertable = (wait_work_item->Flags & WT_EXECUTEINIOTHREAD) ? TRUE : FALSE;
|
||||
HANDLE handles[2] = { wait_work_item->Object, wait_work_item->CancelEvent };
|
||||
HANDLE completion_event;
|
||||
DWORD status;
|
||||
|
||||
|
||||
while (TRUE)
|
||||
{
|
||||
status = WaitForMultipleObjectsEx( 2, handles, FALSE, wait_work_item->Milliseconds, alertable );
|
||||
if (status == STATUS_WAIT_0 || status == STATUS_TIMEOUT)
|
||||
{
|
||||
BOOL TimerOrWaitFired = (status == STATUS_WAIT_0) ? FALSE : TRUE;
|
||||
|
||||
wait_work_item->CallbackInProgress = TRUE;
|
||||
wait_work_item->Callback( wait_work_item->Context, TimerOrWaitFired );
|
||||
wait_work_item->CallbackInProgress = FALSE;
|
||||
|
||||
if (wait_work_item->Flags & WT_EXECUTEONLYONCE)
|
||||
break;
|
||||
}
|
||||
else
|
||||
break; //CancelEvent signalled
|
||||
}
|
||||
|
||||
completion_event = wait_work_item->CompletionEvent;
|
||||
if (completion_event)
|
||||
SetEvent( completion_event );
|
||||
|
||||
if ( InterlockedIncrement( &wait_work_item->DeleteCount ) == 2 )
|
||||
delete_wait_work_item( wait_work_item );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT RegisterWaitForSingleObject_new=RegisterWaitForSingleObject */
|
||||
BOOL WINAPI RegisterWaitForSingleObject_new(PHANDLE phNewWaitObject, HANDLE hObject, WAITORTIMERCALLBACK Callback,
|
||||
PVOID Context, ULONG dwMilliseconds, ULONG dwFlags)
|
||||
{
|
||||
//validate stuff first. we aren't Wine.
|
||||
if (!phNewWaitObject || IsBadCodePtr((FARPROC)Callback) || WaitForSingleObject(hObject,0) == WAIT_FAILED)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
wait_work_item_ptr wait_work_item;
|
||||
wait_work_item = (wait_work_item_ptr)HeapAlloc(GetProcessHeap(), 0, sizeof(*wait_work_item));
|
||||
|
||||
if (!wait_work_item)
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( dwMilliseconds == 0 ) dwFlags |= WT_EXECUTEONLYONCE;
|
||||
wait_work_item->Object = hObject;
|
||||
wait_work_item->Callback = Callback;
|
||||
wait_work_item->Context = Context;
|
||||
wait_work_item->Milliseconds = dwMilliseconds;
|
||||
wait_work_item->Flags = dwFlags;
|
||||
wait_work_item->CallbackInProgress = FALSE;
|
||||
wait_work_item->DeleteCount = 0;
|
||||
wait_work_item->CompletionEvent = NULL;
|
||||
wait_work_item->CancelEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
|
||||
if (!wait_work_item->CancelEvent)
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, wait_work_item );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( !QueueUserWorkItem_new(wait_thread_proc, wait_work_item, dwFlags) )
|
||||
{
|
||||
delete_wait_work_item( wait_work_item );
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
*phNewWaitObject = (HANDLE)wait_work_item;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT RegisterWaitForSingleObjectEx_new=RegisterWaitForSingleObjectEx */
|
||||
HANDLE WINAPI RegisterWaitForSingleObjectEx_new(HANDLE hObject,
|
||||
WAITORTIMERCALLBACK Callback, PVOID Context,
|
||||
ULONG dwMilliseconds, ULONG dwFlags)
|
||||
{
|
||||
HANDLE retHandle;
|
||||
if ( RegisterWaitForSingleObject_new(&retHandle,hObject,Callback,Context,dwMilliseconds,dwFlags) )
|
||||
return retHandle;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT UnregisterWaitEx_new=UnregisterWaitEx */
|
||||
BOOL WINAPI UnregisterWaitEx_new(HANDLE WaitHandle, HANDLE CompletionEvent)
|
||||
{
|
||||
if (!WaitHandle)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
BOOL pending = FALSE;
|
||||
wait_work_item_ptr wait_work_item = (wait_work_item_ptr)WaitHandle;
|
||||
if ( !SetEvent( wait_work_item->CancelEvent ) ) //signal cancel
|
||||
return FALSE;
|
||||
if (wait_work_item->CallbackInProgress)
|
||||
{
|
||||
if (CompletionEvent != NULL)
|
||||
{
|
||||
if (CompletionEvent == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
CompletionEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
|
||||
if (!CompletionEvent)
|
||||
return FALSE;
|
||||
InterlockedExchangePointer( &wait_work_item->CompletionEvent, CompletionEvent );
|
||||
if (wait_work_item->CallbackInProgress)
|
||||
WaitForSingleObject( CompletionEvent, INFINITE );
|
||||
CloseHandle( CompletionEvent );
|
||||
}
|
||||
else
|
||||
{
|
||||
InterlockedExchangePointer( &wait_work_item->CompletionEvent, CompletionEvent );
|
||||
if (wait_work_item->CallbackInProgress)
|
||||
pending = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
pending = TRUE;
|
||||
}
|
||||
|
||||
if ( InterlockedIncrement(&wait_work_item->DeleteCount) == 2 )
|
||||
{
|
||||
pending = FALSE; //somehow callback is complete already
|
||||
delete_wait_work_item( wait_work_item );
|
||||
}
|
||||
if ( pending )
|
||||
{
|
||||
SetLastError(ERROR_IO_PENDING);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT UnregisterWait_new=UnregisterWait */
|
||||
BOOL WINAPI UnregisterWait_new(HANDLE WaitHandle)
|
||||
{
|
||||
return UnregisterWaitEx_new(WaitHandle,NULL);
|
||||
}
|
427
apilibs/kexbasen/kernel32/TlsExt.c
Executable file
427
apilibs/kexbasen/kernel32/TlsExt.c
Executable file
@ -0,0 +1,427 @@
|
||||
/*
|
||||
* KernelEx
|
||||
* Copyright (C) 2009, Xeno86
|
||||
*
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
* KernelEx is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* KernelEx is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include "k32ord.h"
|
||||
#include "kexcoresdk.h"
|
||||
#include "../../../core/structs.h"
|
||||
|
||||
/*
|
||||
* Design note:
|
||||
*
|
||||
* We use last TLS slot (79) specially, storing there
|
||||
* a pointer to extended TLS slot table.
|
||||
*/
|
||||
|
||||
#define __ASM_IS_L33T__
|
||||
|
||||
#define TLS_SIZE 80 /* size of TDB98->TlsSlots */
|
||||
#define TLS_BITMAP_SIZE 3 /* size of PDB98->tlsInUseBits */
|
||||
#define EXT_TLS_SIZE 1024
|
||||
#define EXT_TLS_BITMAP_SIZE ((EXT_TLS_SIZE - 1) / (8 * sizeof(DWORD)) + 1)
|
||||
#define TOTAL_TLS_SIZE (TLS_SIZE-1 + EXT_TLS_SIZE)
|
||||
|
||||
/* Process extended TLS bitmap. */
|
||||
static DWORD ExtTlsBitmap[EXT_TLS_BITMAP_SIZE];
|
||||
|
||||
/* Pointer to TlsLock in kernel32. */
|
||||
static CRITICAL_SECTION* TlsLock;
|
||||
static CRITICAL_SECTION* k32lock;
|
||||
static DWORD lasterror_offs;
|
||||
|
||||
static LPVOID* AllocExtTlsSlots()
|
||||
{
|
||||
LPVOID* p;
|
||||
p = (LPVOID*) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LPVOID) * EXT_TLS_SIZE);
|
||||
if (!p)
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return p;
|
||||
}
|
||||
|
||||
static CRITICAL_SECTION* find_TlsLock()
|
||||
{
|
||||
PROC pTlsAlloc = kexGetProcAddress(GetModuleHandle("KERNEL32"), "TlsAlloc");
|
||||
return *(CRITICAL_SECTION**)((DWORD) pTlsAlloc + 2);
|
||||
}
|
||||
|
||||
static inline
|
||||
PDB98* get_pdb(void)
|
||||
{
|
||||
TIB98* tib;
|
||||
__asm mov eax, fs:18h;
|
||||
__asm mov tib, eax;
|
||||
return tib->pProcess;
|
||||
}
|
||||
|
||||
/* initialization */
|
||||
BOOL init_exttls(void)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
PDB98* pdb = get_pdb();
|
||||
DWORD GV = kexGetVersion();
|
||||
|
||||
//offsets for GetLastError value differ
|
||||
//between systems :(
|
||||
//we set them here
|
||||
if (GV == 0xc0000a04) //98
|
||||
{
|
||||
lasterror_offs = 0x60;
|
||||
}
|
||||
else if (GV == 0xc0005a04) //Me
|
||||
{
|
||||
lasterror_offs = 0x74;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//find TlsLock
|
||||
TlsLock = find_TlsLock();
|
||||
k32lock = (CRITICAL_SECTION*) kexGetK32Lock();
|
||||
|
||||
_EnterSysLevel(TlsLock);
|
||||
|
||||
//check if TLS index 79 free
|
||||
if (!(pdb->tlsInUseBits[2] & (1 << 15)))
|
||||
{
|
||||
//reserve TLS index 79
|
||||
pdb->tlsInUseBits[2] |= (1 << 15);
|
||||
ret = TRUE;
|
||||
}
|
||||
|
||||
_LeaveSysLevel(TlsLock);
|
||||
|
||||
if (!ret)
|
||||
kexDebugPrint("init_exttls failed");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void detach_exttls(void)
|
||||
{
|
||||
TDB98* tdb;
|
||||
LPVOID* ext;
|
||||
|
||||
__asm mov eax, fs:18h;
|
||||
__asm sub eax, 8;
|
||||
__asm mov tdb, eax;
|
||||
|
||||
ext = (LPVOID*) tdb->TlsSlots[TLS_SIZE-1];
|
||||
if (ext)
|
||||
HeapFree(GetProcessHeap(), 0, ext);
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT TlsAlloc_new=TlsAlloc */
|
||||
DWORD WINAPI TlsAlloc_new(void)
|
||||
{
|
||||
PDB98* pdb;
|
||||
DWORD index = 0;
|
||||
int i;
|
||||
|
||||
pdb = get_pdb();
|
||||
|
||||
_EnterSysLevel(TlsLock);
|
||||
|
||||
for (i = 0 ; i < TLS_BITMAP_SIZE ; i++, index += 32)
|
||||
{
|
||||
if (pdb->tlsInUseBits[i] == 0xffffffff)
|
||||
continue;
|
||||
|
||||
for (int j = 0, a = 1 ; j < 32, index < TLS_SIZE-1 ; j++, a <<= 1, index++)
|
||||
{
|
||||
if ((pdb->tlsInUseBits[i] & a) == 0)
|
||||
{
|
||||
pdb->tlsInUseBits[i] |= a;
|
||||
_LeaveSysLevel(TlsLock);
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0 ; i < EXT_TLS_BITMAP_SIZE ; i++, index += 32)
|
||||
{
|
||||
if (ExtTlsBitmap[i] == 0xffffffff)
|
||||
continue;
|
||||
|
||||
for (int j = 0, a = 1 ; j < 32, index < TOTAL_TLS_SIZE ; j++, a <<= 1, index++)
|
||||
{
|
||||
if ((ExtTlsBitmap[i] & a) == 0)
|
||||
{
|
||||
ExtTlsBitmap[i] |= a;
|
||||
_LeaveSysLevel(TlsLock);
|
||||
return index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_LeaveSysLevel(TlsLock);
|
||||
|
||||
SetLastError(ERROR_NO_MORE_ITEMS);
|
||||
return TLS_OUT_OF_INDEXES;
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT TlsFree_new=TlsFree */
|
||||
BOOL WINAPI TlsFree_new(DWORD dwTlsIndex)
|
||||
{
|
||||
int ret;
|
||||
PDB98* pdb = get_pdb();
|
||||
|
||||
_EnterSysLevel(TlsLock);
|
||||
|
||||
if (dwTlsIndex < TLS_SIZE-1)
|
||||
{
|
||||
int rem = dwTlsIndex % (sizeof(DWORD) * 8);
|
||||
int div = dwTlsIndex / (sizeof(DWORD) * 8);
|
||||
pdb->tlsInUseBits[div] &= ~(1 << rem);
|
||||
ret = 1;
|
||||
}
|
||||
else if (dwTlsIndex < TOTAL_TLS_SIZE)
|
||||
{
|
||||
dwTlsIndex -= TLS_SIZE-1;
|
||||
int rem = dwTlsIndex % (sizeof(DWORD) * 8);
|
||||
int div = dwTlsIndex / (sizeof(DWORD) * 8);
|
||||
ExtTlsBitmap[div] &= ~(1 << rem);
|
||||
ret = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (ret)
|
||||
{
|
||||
const NODE* thread;
|
||||
|
||||
_EnterSysLevel(k32lock);
|
||||
|
||||
for (thread = pdb->ThreadList->firstNode ; thread != NULL ; thread = thread->next)
|
||||
{
|
||||
TDB98* tdb = (TDB98*) thread->data;
|
||||
if (ret == 1)
|
||||
tdb->TlsSlots[dwTlsIndex] = NULL;
|
||||
else
|
||||
{
|
||||
LPVOID* ext = (LPVOID*) tdb->TlsSlots[TLS_SIZE-1];
|
||||
if (ext)
|
||||
ext[dwTlsIndex] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
_LeaveSysLevel(k32lock);
|
||||
}
|
||||
|
||||
_LeaveSysLevel(TlsLock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef __ASM_IS_L33T__
|
||||
|
||||
/* MAKE_EXPORT TlsGetValue_new2=TlsGetValue */
|
||||
__declspec(naked)
|
||||
LPVOID WINAPI TlsGetValue_new2(DWORD dwTlsIndex)
|
||||
{
|
||||
__asm {
|
||||
mov ecx, [esp+4] ;dwTlsIndex
|
||||
mov edx, fs:18h // Thread Info Block
|
||||
cmp ecx, TLS_SIZE-1
|
||||
jnb __more
|
||||
mov eax, [edx+ecx*4+88h]
|
||||
__exit_no_error:
|
||||
mov ecx, lasterror_offs
|
||||
mov dword ptr [edx+ecx], NO_ERROR
|
||||
__exit:
|
||||
retn 4
|
||||
__more:
|
||||
cmp ecx, TOTAL_TLS_SIZE
|
||||
jnb __error
|
||||
mov eax, [edx+(TLS_SIZE-1)*4+88h]
|
||||
test eax, eax
|
||||
jz __exit_no_error
|
||||
sub ecx, TLS_SIZE-1
|
||||
mov eax, [eax+ecx*4]
|
||||
jmp __exit_no_error
|
||||
__error:
|
||||
mov ecx, lasterror_offs
|
||||
mov dword ptr [edx+ecx], ERROR_INVALID_PARAMETER
|
||||
xor eax, eax
|
||||
jmp __exit
|
||||
}
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT TlsSetValue_new2=TlsSetValue */
|
||||
__declspec(naked)
|
||||
BOOL WINAPI TlsSetValue_new2(DWORD dwTlsIndex, LPVOID lpTlsValue)
|
||||
{
|
||||
__asm {
|
||||
mov ecx, [esp+4] ;dwTlsIndex
|
||||
mov edx, fs:18h // Thread Info Block
|
||||
cmp ecx, TLS_SIZE-1
|
||||
jnb __more
|
||||
mov eax, [esp+8] ;lpTlsValue
|
||||
mov [edx+ecx*4+88h], eax
|
||||
__exit_no_error:
|
||||
mov eax, 1
|
||||
__exit:
|
||||
retn 8
|
||||
__more:
|
||||
cmp ecx, TOTAL_TLS_SIZE
|
||||
jnb __error
|
||||
mov eax, [edx+(TLS_SIZE-1)*4+88h]
|
||||
test eax, eax
|
||||
jz __alloc
|
||||
__no_alloc:
|
||||
mov edx, [esp+8] ;lpTlsValue
|
||||
sub ecx, TLS_SIZE-1
|
||||
mov [eax+ecx*4], edx
|
||||
jmp __exit_no_error
|
||||
__alloc:
|
||||
call AllocExtTlsSlots
|
||||
test eax, eax
|
||||
jz __exit
|
||||
mov ecx, fs:18h
|
||||
lea edx, [ecx+(TLS_SIZE-1)*4+88h]
|
||||
mov [edx], eax
|
||||
mov ecx, [esp+4] ;dwTlsIndex
|
||||
jmp __no_alloc
|
||||
__error:
|
||||
mov ecx, lasterror_offs
|
||||
mov dword ptr [edx+ecx], ERROR_INVALID_PARAMETER
|
||||
xor eax, eax
|
||||
jmp __exit
|
||||
}
|
||||
}
|
||||
|
||||
#else //__ASM_IS_L33T__
|
||||
|
||||
static inline void SetLastError_fast(TDB98* tdb, DWORD error)
|
||||
{
|
||||
*(DWORD*) ((DWORD) tdb + lasterror_offs + 8) = error;
|
||||
}
|
||||
|
||||
LPVOID WINAPI TlsGetValue_new2(DWORD dwTlsIndex)
|
||||
{
|
||||
TDB98* tdb;
|
||||
|
||||
__asm mov eax, fs:18h;
|
||||
__asm sub eax, 8;
|
||||
__asm mov tdb, eax;
|
||||
|
||||
if (dwTlsIndex < TLS_SIZE-1)
|
||||
{
|
||||
SetLastError_fast(tdb, NO_ERROR);
|
||||
return tdb->TlsSlots[dwTlsIndex];
|
||||
}
|
||||
else if (dwTlsIndex < TOTAL_TLS_SIZE)
|
||||
{
|
||||
LPVOID* ext;
|
||||
ext = (LPVOID*) tdb->TlsSlots[TLS_SIZE-1];
|
||||
if (ext)
|
||||
return ext[dwTlsIndex-TLS_SIZE-1];
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError_fast(tdb, ERROR_INVALID_PARAMETER);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL WINAPI TlsSetValue_new2(DWORD dwTlsIndex, LPVOID lpTlsValue)
|
||||
{
|
||||
TDB98* tdb;
|
||||
|
||||
__asm mov eax, fs:18h;
|
||||
__asm sub eax, 8;
|
||||
__asm mov tdb, eax;
|
||||
|
||||
if (dwTlsIndex < TLS_SIZE-1)
|
||||
{
|
||||
tdb->TlsSlots[dwTlsIndex] = lpTlsValue;
|
||||
return TRUE;
|
||||
}
|
||||
else if (dwTlsIndex < TOTAL_TLS_SIZE)
|
||||
{
|
||||
LPVOID* ext = (LPVOID*) tdb->TlsSlots[TLS_SIZE-1];
|
||||
if (!ext)
|
||||
{
|
||||
ext = AllocExtTlsSlots();
|
||||
if (!ext)
|
||||
return FALSE;
|
||||
tdb->TlsSlots[TLS_SIZE-1] = ext;
|
||||
}
|
||||
ext[dwTlsIndex-TLS_SIZE-1] = lpTlsValue;
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetLastError_fast(tdb, ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ORIGINAL UNALTERED FUNCTION AS REFERENCE
|
||||
__declspec(naked)
|
||||
LPVOID WINAPI TlsGetValue_new(DWORD dwTlsIndex)
|
||||
{
|
||||
__asm {
|
||||
mov ecx, dwTlsIndex
|
||||
mov edx, fs:18h // Thread Info Block
|
||||
cmp ecx, 50h
|
||||
jnb __error
|
||||
mov eax, [edx+ecx*4+88h]
|
||||
mov dword ptr [edx+60h], NO_ERROR
|
||||
__exit:
|
||||
retn 4
|
||||
__error:
|
||||
mov dword ptr [edx+60h], ERROR_INVALID_PARAMETER //Me:[edx+74h]
|
||||
xor eax, eax
|
||||
jmp __exit
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/* ORIGINAL UNALTERED FUNCTION AS REFERENCE
|
||||
__declspec(naked)
|
||||
BOOL WINAPI TlsSetValue_new(DWORD dwTlsIndex, LPVOID lpTlsValue)
|
||||
{
|
||||
__asm {
|
||||
mov ecx, dwTlsIndex
|
||||
mov edx, fs:18h // Thread Info Block
|
||||
cmp ecx, 50h
|
||||
jnb __error
|
||||
mov eax, lpTlsValue
|
||||
mov [edx+ecx*4+88h], eax
|
||||
mov eax, 1
|
||||
__exit:
|
||||
retn 8
|
||||
__error:
|
||||
mov dword ptr [edx+60h], ERROR_INVALID_PARAMETER //Me:[edx+74h]
|
||||
xor eax, eax
|
||||
jmp __exit
|
||||
}
|
||||
}
|
||||
*/
|
33
apilibs/kexbasen/kernel32/_kernel32_apilist.c
Normal file → Executable file
33
apilibs/kexbasen/kernel32/_kernel32_apilist.c
Normal file → Executable file
@ -23,9 +23,24 @@
|
||||
#include "kexcoresdk.h"
|
||||
#include "_kernel32_apilist.h"
|
||||
|
||||
extern BOOL init_jemalloc();
|
||||
extern BOOL init_exttls();
|
||||
extern void uninit_jemalloc();
|
||||
extern void detach_exttls();
|
||||
|
||||
BOOL init_kernel32()
|
||||
{
|
||||
return TRUE;
|
||||
return init_jemalloc() && init_exttls();
|
||||
}
|
||||
|
||||
void uninit_kernel32()
|
||||
{
|
||||
uninit_jemalloc();
|
||||
}
|
||||
|
||||
void detach_kernel32()
|
||||
{
|
||||
detach_exttls();
|
||||
}
|
||||
|
||||
static const apilib_named_api kernel32_named_apis[] =
|
||||
@ -42,6 +57,7 @@ static const apilib_named_api kernel32_named_apis[] =
|
||||
DECL_API("CreateProcessW", CreateProcessW_fwd),
|
||||
DECL_API("CreateSemaphoreW", CreateSemaphoreW_fwd),
|
||||
DECL_API("CreateWaitableTimerW", CreateWaitableTimerW_fwd),
|
||||
DECL_API("DelayLoadFailureHook", DelayLoadFailureHook_new),
|
||||
DECL_API("EnumCalendarInfoExW", EnumCalendarInfoExW_fwd),
|
||||
DECL_API("EnumCalendarInfoW", EnumCalendarInfoW_fwd),
|
||||
DECL_API("EnumDateFormatsExW", EnumDateFormatsExW_fwd),
|
||||
@ -75,6 +91,12 @@ static const apilib_named_api kernel32_named_apis[] =
|
||||
DECL_API("GetProfileStringW", GetProfileStringW_fwd),
|
||||
DECL_API("GetTimeFormatW", GetTimeFormatW_fwd),
|
||||
DECL_API("GetVolumeInformationW", GetVolumeInformationW_fwd),
|
||||
DECL_API("HeapAlloc", HeapAlloc_new),
|
||||
DECL_API("HeapCreate", HeapCreate_new),
|
||||
DECL_API("HeapDestroy", HeapDestroy_new),
|
||||
DECL_API("HeapFree", HeapFree_new),
|
||||
DECL_API("HeapReAlloc", HeapReAlloc_new),
|
||||
DECL_API("HeapSize", HeapSize_new),
|
||||
DECL_API("IsBadStringPtrW", IsBadStringPtrW_fwd),
|
||||
DECL_API("OpenEventW", OpenEventW_fwd),
|
||||
DECL_API("OpenFileMappingW", OpenFileMappingW_fwd),
|
||||
@ -83,10 +105,13 @@ static const apilib_named_api kernel32_named_apis[] =
|
||||
DECL_API("OpenWaitableTimerW", OpenWaitableTimerW_fwd),
|
||||
DECL_API("PeekConsoleInputW", PeekConsoleInputW_fwd),
|
||||
DECL_API("QueryDosDeviceW", QueryDosDeviceW_fwd),
|
||||
DECL_API("QueueUserWorkItem", QueueUserWorkItem_new),
|
||||
DECL_API("ReadConsoleInputW", ReadConsoleInputW_fwd),
|
||||
DECL_API("ReadConsoleOutputCharacterW", ReadConsoleOutputCharacterW_fwd),
|
||||
DECL_API("ReadConsoleOutputW", ReadConsoleOutputW_fwd),
|
||||
DECL_API("ReadConsoleW", ReadConsoleW_fwd),
|
||||
DECL_API("RegisterWaitForSingleObject", RegisterWaitForSingleObject_new),
|
||||
DECL_API("RegisterWaitForSingleObjectEx", RegisterWaitForSingleObjectEx_new),
|
||||
DECL_API("ScrollConsoleScreenBufferW", ScrollConsoleScreenBufferW_fwd),
|
||||
DECL_API("SetCalendarInfoW", SetCalendarInfoW_fwd),
|
||||
DECL_API("SetComputerNameW", SetComputerNameW_fwd),
|
||||
@ -94,6 +119,12 @@ static const apilib_named_api kernel32_named_apis[] =
|
||||
DECL_API("SetEnvironmentVariableW", SetEnvironmentVariableW_fwd),
|
||||
DECL_API("SetLocaleInfoW", SetLocaleInfoW_fwd),
|
||||
DECL_API("SetVolumeLabelW", SetVolumeLabelW_fwd),
|
||||
DECL_API("TlsAlloc", TlsAlloc_new),
|
||||
DECL_API("TlsFree", TlsFree_new),
|
||||
DECL_API("TlsGetValue", TlsGetValue_new2),
|
||||
DECL_API("TlsSetValue", TlsSetValue_new2),
|
||||
DECL_API("UnregisterWait", UnregisterWait_new),
|
||||
DECL_API("UnregisterWaitEx", UnregisterWaitEx_new),
|
||||
DECL_API("WaitNamedPipeW", WaitNamedPipeW_fwd),
|
||||
DECL_API("WriteConsoleInputW", WriteConsoleInputW_fwd),
|
||||
DECL_API("WriteConsoleOutputCharacterW", WriteConsoleOutputCharacterW_fwd),
|
||||
|
20
apilibs/kexbasen/kernel32/_kernel32_apilist.h
Normal file → Executable file
20
apilibs/kexbasen/kernel32/_kernel32_apilist.h
Normal file → Executable file
@ -25,9 +25,29 @@
|
||||
#include "kexcoresdk.h"
|
||||
|
||||
BOOL init_kernel32();
|
||||
void uninit_kernel32();
|
||||
void detach_kernel32();
|
||||
extern const apilib_api_table apitable_kernel32;
|
||||
|
||||
/*** AUTOGENERATED APILIST DECLARATIONS BEGIN ***/
|
||||
FARPROC WINAPI DelayLoadFailureHook_new(LPSTR pszDllName, LPSTR pszProcName);
|
||||
BOOL WINAPI QueueUserWorkItem_new(LPTHREAD_START_ROUTINE Function, PVOID Context, ULONG Flags);
|
||||
BOOL WINAPI RegisterWaitForSingleObject_new(PHANDLE phNewWaitObject, HANDLE hObject, WAITORTIMERCALLBACK Callback, PVOID Context, ULONG dwMilliseconds, ULONG dwFlags);
|
||||
HANDLE WINAPI RegisterWaitForSingleObjectEx_new(HANDLE hObject, WAITORTIMERCALLBACK Callback, PVOID Context, ULONG dwMilliseconds, ULONG dwFlags);
|
||||
BOOL WINAPI UnregisterWaitEx_new(HANDLE WaitHandle, HANDLE CompletionEvent);
|
||||
BOOL WINAPI UnregisterWait_new(HANDLE WaitHandle);
|
||||
DWORD WINAPI TlsAlloc_new(void);
|
||||
BOOL WINAPI TlsFree_new(DWORD dwTlsIndex);
|
||||
LPVOID WINAPI TlsGetValue_new2(DWORD dwTlsIndex);
|
||||
BOOL WINAPI TlsSetValue_new2(DWORD dwTlsIndex, LPVOID lpTlsValue);
|
||||
LPVOID WINAPI TlsGetValue_new2(DWORD dwTlsIndex);
|
||||
BOOL WINAPI TlsSetValue_new2(DWORD dwTlsIndex, LPVOID lpTlsValue);
|
||||
HANDLE WINAPI HeapCreate_new(DWORD flOptions, DWORD dwInitialSize, DWORD dwMaximumSize);
|
||||
BOOL WINAPI HeapDestroy_new(HANDLE hHeap);
|
||||
LPVOID WINAPI HeapAlloc_new(HANDLE hHeap, DWORD dwFlags, DWORD dwBytes);
|
||||
BOOL WINAPI HeapFree_new(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem);
|
||||
DWORD WINAPI HeapSize_new(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem);
|
||||
LPVOID WINAPI HeapReAlloc_new(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, DWORD dwBytes);
|
||||
FWDPROC BuildCommDCBAndTimeoutsW_fwd;
|
||||
FWDPROC BuildCommDCBW_fwd;
|
||||
FWDPROC CallNamedPipeW_fwd;
|
||||
|
268
apilibs/kexbasen/kernel32/allocator.c
Executable file
268
apilibs/kexbasen/kernel32/allocator.c
Executable file
@ -0,0 +1,268 @@
|
||||
/*
|
||||
* KernelEx
|
||||
* Copyright (C) 2009, Xeno86
|
||||
*
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
* KernelEx is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* KernelEx is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
/************************************************************************/
|
||||
/* N O T E S */
|
||||
/************************************************************************/
|
||||
|
||||
/* Shared heap and default process heap (GetProcessHeap) is handled by
|
||||
* standard system implementation. This releases us from the hassle of
|
||||
* making special hacks for handling GlobalAlloc and LocalAlloc.
|
||||
* This covers 99% of applications.
|
||||
*
|
||||
* One custom heap is used per process, regardless of the number of
|
||||
* HeapCreate calls. Two distinct handle values are used to indicate
|
||||
* belonging to jemalloc and whether HEAP_GENERATE_EXCEPTIONS flag
|
||||
* was set.
|
||||
* All calls which do not have our handles are forwarded to system.
|
||||
*
|
||||
* One arena is used and TLS usage is disabled for optimal performance
|
||||
* on single processor system. HEAP_NO_SERIALIZE flag is ignored
|
||||
* because there is single heap per process.
|
||||
*/
|
||||
|
||||
/************************************************************************/
|
||||
/* M A C R O S A N D W R A P P E R S */
|
||||
/************************************************************************/
|
||||
|
||||
#define malloc(a) je_malloc(a)
|
||||
#define valloc(a) je_valloc(a)
|
||||
#define calloc(a, b) je_calloc(a, b)
|
||||
#define realloc(a, b) je_realloc(a, b)
|
||||
#define free(a) je_free(a)
|
||||
|
||||
#define MOZ_MEMORY
|
||||
#define MOZ_MEMORY_WINDOWS
|
||||
#define NO_TLS
|
||||
|
||||
#if (_MSC_VER < 1300)
|
||||
#define __STDC_LIMIT_MACROS
|
||||
#include "stdint.h"
|
||||
#endif
|
||||
|
||||
#include "jemalloc/jemalloc.c"
|
||||
|
||||
int* _errno(void)
|
||||
{
|
||||
static int myerrno = 0;
|
||||
return &myerrno;
|
||||
}
|
||||
|
||||
#define TAG(A, B, C, D) (ULONG)(((A)<<0) + ((B)<<8) + ((C)<<16) + ((D)<<24))
|
||||
#define JM_HEAP_NORM ((HANDLE) TAG('J','E','M','N'))
|
||||
#define JM_HEAP_EXCP ((HANDLE) TAG('J','E','M','E'))
|
||||
|
||||
#define HEAP_SHARED 0x04000000
|
||||
|
||||
BOOL init_jemalloc()
|
||||
{
|
||||
if (malloc_init_hard())
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void uninit_jemalloc()
|
||||
{
|
||||
malloc_print_stats();
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
/* T H E C O D E */
|
||||
/************************************************************************/
|
||||
|
||||
typedef union
|
||||
{
|
||||
BYTE db;
|
||||
WORD dw;
|
||||
DWORD dd;
|
||||
} UFooter;
|
||||
|
||||
static inline
|
||||
int footer_size(DWORD alloc_bytes)
|
||||
{
|
||||
if (alloc_bytes <= 256 - 1)
|
||||
return 1;
|
||||
else if (alloc_bytes < 64*1024 - 2)
|
||||
return 2;
|
||||
else
|
||||
return 4;
|
||||
}
|
||||
|
||||
static inline
|
||||
int footer_size_for_usable_size(size_t usable)
|
||||
{
|
||||
if (usable <= 256)
|
||||
return 1;
|
||||
else if (usable <= 64*1024)
|
||||
return 2;
|
||||
else
|
||||
return 4;
|
||||
}
|
||||
|
||||
static inline
|
||||
DWORD read_footer(const void* ptr, size_t usable, int fs)
|
||||
{
|
||||
UFooter* footer;
|
||||
if (!ptr)
|
||||
return 0;
|
||||
footer = (UFooter*) ((DWORD) ptr + usable - fs);
|
||||
if (fs == sizeof(BYTE))
|
||||
return footer->db;
|
||||
else if (fs == sizeof(WORD))
|
||||
return footer->dw;
|
||||
else
|
||||
return footer->dd;
|
||||
}
|
||||
|
||||
static inline
|
||||
void write_footer(void* ptr, size_t usable, int fs, DWORD value)
|
||||
{
|
||||
UFooter* footer = (UFooter*) ((DWORD) ptr + usable - fs);
|
||||
if (fs == sizeof(BYTE))
|
||||
footer->db = (BYTE) value;
|
||||
else if (fs == sizeof(WORD))
|
||||
footer->dw = (WORD) value;
|
||||
else
|
||||
footer->dd = (DWORD) value;
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT HeapCreate_new=HeapCreate */
|
||||
HANDLE WINAPI HeapCreate_new(DWORD flOptions, DWORD dwInitialSize, DWORD dwMaximumSize)
|
||||
{
|
||||
if (flOptions & HEAP_SHARED)
|
||||
return HeapCreate(flOptions, dwInitialSize, dwMaximumSize);
|
||||
if (flOptions & HEAP_GENERATE_EXCEPTIONS)
|
||||
return JM_HEAP_EXCP;
|
||||
else
|
||||
return JM_HEAP_NORM;
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT HeapDestroy_new=HeapDestroy */
|
||||
BOOL WINAPI HeapDestroy_new(HANDLE hHeap)
|
||||
{
|
||||
if (hHeap == JM_HEAP_NORM || hHeap == JM_HEAP_EXCP)
|
||||
return TRUE;
|
||||
else
|
||||
return HeapDestroy(hHeap);
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT HeapAlloc_new=HeapAlloc */
|
||||
LPVOID WINAPI HeapAlloc_new(HANDLE hHeap, DWORD dwFlags, DWORD dwBytes)
|
||||
{
|
||||
if (hHeap == JM_HEAP_NORM || hHeap == JM_HEAP_EXCP)
|
||||
{
|
||||
LPVOID ret;
|
||||
int fs = footer_size(dwBytes);
|
||||
|
||||
if (dwFlags & HEAP_ZERO_MEMORY)
|
||||
ret = calloc(1, dwBytes + fs);
|
||||
else
|
||||
ret = malloc(dwBytes + fs);
|
||||
if (!ret && (hHeap == JM_HEAP_EXCP || (dwFlags & HEAP_GENERATE_EXCEPTIONS)))
|
||||
RaiseException(STATUS_NO_MEMORY, 0, 0, NULL);
|
||||
|
||||
if (ret)
|
||||
write_footer(ret, malloc_usable_size(ret), fs, dwBytes);
|
||||
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
return HeapAlloc(hHeap, dwFlags, dwBytes);
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT HeapFree_new=HeapFree */
|
||||
BOOL WINAPI HeapFree_new(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem)
|
||||
{
|
||||
if (hHeap == JM_HEAP_NORM || hHeap == JM_HEAP_EXCP)
|
||||
{
|
||||
free(lpMem);
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
return HeapFree(hHeap, dwFlags, lpMem);
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT HeapSize_new=HeapSize */
|
||||
DWORD WINAPI HeapSize_new(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem)
|
||||
{
|
||||
if (hHeap == JM_HEAP_NORM || hHeap == JM_HEAP_EXCP)
|
||||
{
|
||||
size_t usable = malloc_usable_size(lpMem);
|
||||
int fs = footer_size_for_usable_size(usable);
|
||||
|
||||
return read_footer(lpMem, usable, fs);
|
||||
}
|
||||
else
|
||||
return HeapSize(hHeap, dwFlags, lpMem);
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT HeapReAlloc_new=HeapReAlloc */
|
||||
LPVOID WINAPI HeapReAlloc_new(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, DWORD dwBytes)
|
||||
{
|
||||
if (hHeap == JM_HEAP_NORM || hHeap == JM_HEAP_EXCP)
|
||||
{
|
||||
LPVOID ret;
|
||||
int fs = footer_size(dwBytes);
|
||||
size_t usable = malloc_usable_size(lpMem);
|
||||
|
||||
if (dwFlags & HEAP_REALLOC_IN_PLACE_ONLY)
|
||||
{
|
||||
if (usable > dwBytes + fs)
|
||||
{
|
||||
size_t fsu = footer_size_for_usable_size(usable);
|
||||
if (dwFlags & HEAP_ZERO_MEMORY)
|
||||
{
|
||||
DWORD old = read_footer(lpMem, usable, fsu);
|
||||
if (dwBytes > old)
|
||||
memset((void*) ((DWORD) lpMem + old), 0, dwBytes - old);
|
||||
}
|
||||
|
||||
write_footer(lpMem, usable, fsu, dwBytes);
|
||||
ret = lpMem;
|
||||
}
|
||||
else
|
||||
ret = NULL;
|
||||
}
|
||||
else if (dwFlags & HEAP_ZERO_MEMORY)
|
||||
{
|
||||
DWORD old = read_footer(lpMem, usable, footer_size_for_usable_size(usable));
|
||||
ret = realloc(lpMem, dwBytes + fs);
|
||||
if (ret)
|
||||
{
|
||||
if (dwBytes > old)
|
||||
memset((void*) ((DWORD) ret + old), 0, dwBytes - old);
|
||||
write_footer(ret, malloc_usable_size(ret), fs, dwBytes);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = realloc(lpMem, dwBytes + fs);
|
||||
if (ret)
|
||||
write_footer(ret, malloc_usable_size(ret), fs, dwBytes);
|
||||
}
|
||||
if (!ret && (hHeap == JM_HEAP_EXCP || (dwFlags & HEAP_GENERATE_EXCEPTIONS)))
|
||||
RaiseException(STATUS_NO_MEMORY, 0, 0, NULL);
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
return HeapReAlloc(hHeap, dwFlags, lpMem, dwBytes);
|
||||
}
|
||||
|
7270
apilibs/kexbasen/kernel32/jemalloc/jemalloc.c
Executable file
7270
apilibs/kexbasen/kernel32/jemalloc/jemalloc.c
Executable file
File diff suppressed because it is too large
Load Diff
177
apilibs/kexbasen/kernel32/jemalloc/jemalloc.h
Executable file
177
apilibs/kexbasen/kernel32/jemalloc/jemalloc.h
Executable file
@ -0,0 +1,177 @@
|
||||
#ifndef MOZ_MEMORY_WINDOWS
|
||||
# include <stdbool.h>
|
||||
#else
|
||||
# include <windows.h>
|
||||
# ifndef bool
|
||||
# define bool BOOL
|
||||
# endif
|
||||
#endif
|
||||
|
||||
extern const char *_malloc_options;
|
||||
|
||||
/*
|
||||
* jemalloc_stats() is not a stable interface. When using jemalloc_stats_t, be
|
||||
* sure that the compiled results of jemalloc.c are in sync with this header
|
||||
* file.
|
||||
*/
|
||||
typedef struct {
|
||||
/*
|
||||
* Run-time configuration settings.
|
||||
*/
|
||||
bool opt_abort; /* abort(3) on error? */
|
||||
bool opt_junk; /* Fill allocated/free memory with 0xa5/0x5a? */
|
||||
bool opt_utrace; /* Trace all allocation events? */
|
||||
bool opt_sysv; /* SysV semantics? */
|
||||
bool opt_xmalloc; /* abort(3) on OOM? */
|
||||
bool opt_zero; /* Fill allocated memory with 0x0? */
|
||||
size_t narenas; /* Number of arenas. */
|
||||
size_t balance_threshold; /* Arena contention rebalance threshold. */
|
||||
size_t quantum; /* Allocation quantum. */
|
||||
size_t small_max; /* Max quantum-spaced allocation size. */
|
||||
size_t large_max; /* Max sub-chunksize allocation size. */
|
||||
size_t chunksize; /* Size of each virtual memory mapping. */
|
||||
size_t dirty_max; /* Max dirty pages per arena. */
|
||||
size_t reserve_min; /* reserve_low callback threshold. */
|
||||
size_t reserve_max; /* Maximum reserve size before unmapping. */
|
||||
|
||||
/*
|
||||
* Current memory usage statistics.
|
||||
*/
|
||||
size_t mapped; /* Bytes mapped (not necessarily committed). */
|
||||
size_t committed; /* Bytes committed (readable/writable). */
|
||||
size_t allocated; /* Bytes allocted (in use by application). */
|
||||
size_t dirty; /* Bytes dirty (committed unused pages). */
|
||||
size_t reserve_cur; /* Current memory reserve. */
|
||||
} jemalloc_stats_t;
|
||||
|
||||
#ifndef MOZ_MEMORY_DARWIN
|
||||
void *malloc(size_t size);
|
||||
void *valloc(size_t size);
|
||||
void *calloc(size_t num, size_t size);
|
||||
void *realloc(void *ptr, size_t size);
|
||||
void free(void *ptr);
|
||||
#endif
|
||||
|
||||
int posix_memalign(void **memptr, size_t alignment, size_t size);
|
||||
void *memalign(size_t alignment, size_t size);
|
||||
size_t malloc_usable_size(const void *ptr);
|
||||
void jemalloc_stats(jemalloc_stats_t *stats);
|
||||
|
||||
/* The x*() functions never return NULL. */
|
||||
void *xmalloc(size_t size);
|
||||
void *xcalloc(size_t num, size_t size);
|
||||
void *xrealloc(void *ptr, size_t size);
|
||||
void *xmemalign(size_t alignment, size_t size);
|
||||
|
||||
/*
|
||||
* The allocator maintains a memory reserve that is used to satisfy allocation
|
||||
* requests when no additional memory can be acquired from the operating
|
||||
* system. Under normal operating conditions, the reserve size is at least
|
||||
* reserve_min bytes. If the reserve is depleted or insufficient to satisfy an
|
||||
* allocation request, then condition notifications are sent to one or more of
|
||||
* the registered callback functions:
|
||||
*
|
||||
* RESERVE_CND_LOW: The reserve had to be used to satisfy an allocation
|
||||
* request, which dropped the reserve size below the
|
||||
* minimum. The callee should try to free memory in order
|
||||
* to restore the reserve.
|
||||
*
|
||||
* RESERVE_CND_CRIT: The reserve was not large enough to satisfy a pending
|
||||
* allocation request. Some callee must free adequate
|
||||
* memory in order to prevent application failure (unless
|
||||
* the condition spontaneously desists due to concurrent
|
||||
* deallocation).
|
||||
*
|
||||
* RESERVE_CND_FAIL: An allocation request could not be satisfied, despite all
|
||||
* attempts. The allocator is about to terminate the
|
||||
* application.
|
||||
*
|
||||
* The order in which the callback functions are called is only loosely
|
||||
* specified: in the absence of interposing callback
|
||||
* registrations/unregistrations, enabled callbacks will be called in an
|
||||
* arbitrary round-robin order.
|
||||
*
|
||||
* Condition notifications are sent to callbacks only while conditions exist.
|
||||
* For example, just before the allocator sends a RESERVE_CND_LOW condition
|
||||
* notification to a callback, the reserve is in fact depleted. However, due
|
||||
* to allocator concurrency, the reserve may have been restored by the time the
|
||||
* callback function executes. Furthermore, if the reserve is restored at some
|
||||
* point during the delivery of condition notifications to callbacks, no
|
||||
* further deliveries will occur, since the condition no longer exists.
|
||||
*
|
||||
* Callback functions can freely call back into the allocator (i.e. the
|
||||
* allocator releases all internal resources before calling each callback
|
||||
* function), though allocation is discouraged, since recursive callbacks are
|
||||
* likely to result, which places extra burden on the application to avoid
|
||||
* deadlock.
|
||||
*
|
||||
* Callback functions must be thread-safe, since it is possible that multiple
|
||||
* threads will call into the same callback function concurrently.
|
||||
*/
|
||||
|
||||
/* Memory reserve condition types. */
|
||||
typedef enum {
|
||||
RESERVE_CND_LOW,
|
||||
RESERVE_CND_CRIT,
|
||||
RESERVE_CND_FAIL
|
||||
} reserve_cnd_t;
|
||||
|
||||
/*
|
||||
* Reserve condition notification callback function type definition.
|
||||
*
|
||||
* Inputs:
|
||||
* ctx: Opaque application data, as passed to reserve_cb_register().
|
||||
* cnd: Condition type being delivered.
|
||||
* size: Allocation request size for the allocation that caused the condition.
|
||||
*/
|
||||
typedef void reserve_cb_t(void *ctx, reserve_cnd_t cnd, size_t size);
|
||||
|
||||
/*
|
||||
* Register a callback function.
|
||||
*
|
||||
* Inputs:
|
||||
* cb: Callback function pointer.
|
||||
* ctx: Opaque application data, passed to cb().
|
||||
*
|
||||
* Output:
|
||||
* ret: If true, failure due to OOM; success otherwise.
|
||||
*/
|
||||
bool reserve_cb_register(reserve_cb_t *cb, void *ctx);
|
||||
|
||||
/*
|
||||
* Unregister a callback function.
|
||||
*
|
||||
* Inputs:
|
||||
* cb: Callback function pointer.
|
||||
* ctx: Opaque application data, same as that passed to reserve_cb_register().
|
||||
*
|
||||
* Output:
|
||||
* ret: False upon success, true if the {cb,ctx} registration could not be
|
||||
* found.
|
||||
*/
|
||||
bool reserve_cb_unregister(reserve_cb_t *cb, void *ctx);
|
||||
|
||||
/*
|
||||
* Get the current reserve size.
|
||||
*
|
||||
* ret: Current reserve size.
|
||||
*/
|
||||
size_t reserve_cur_get(void);
|
||||
|
||||
/*
|
||||
* Get the minimum acceptable reserve size. If the reserve drops below this
|
||||
* value, the RESERVE_CND_LOW condition notification is sent to the callbacks.
|
||||
*
|
||||
* ret: Minimum acceptable reserve size.
|
||||
*/
|
||||
size_t reserve_min_get(void);
|
||||
|
||||
/*
|
||||
* Set the minimum acceptable reserve size.
|
||||
*
|
||||
* min: Reserve threshold. This value may be internally rounded up.
|
||||
* ret: False if the reserve was successfully resized; true otherwise. Note
|
||||
* that failure to resize the reserve also results in a RESERVE_CND_LOW
|
||||
* condition.
|
||||
*/
|
||||
bool reserve_min_set(size_t min);
|
114
apilibs/kexbasen/kernel32/jemalloc/ql.h
Executable file
114
apilibs/kexbasen/kernel32/jemalloc/ql.h
Executable file
@ -0,0 +1,114 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Jason Evans <jasone@canonware.com>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice(s), this list of conditions and the following disclaimer
|
||||
* unmodified other than the allowable addition of one or more
|
||||
* copyright notices.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice(s), this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/*
|
||||
* List definitions.
|
||||
*/
|
||||
#define ql_head(a_type) \
|
||||
struct { \
|
||||
a_type *qlh_first; \
|
||||
}
|
||||
|
||||
#define ql_head_initializer(a_head) {NULL}
|
||||
|
||||
#define ql_elm(a_type) qr(a_type)
|
||||
|
||||
/* List functions. */
|
||||
#define ql_new(a_head) do { \
|
||||
(a_head)->qlh_first = NULL; \
|
||||
} while (0)
|
||||
|
||||
#define ql_elm_new(a_elm, a_field) qr_new((a_elm), a_field)
|
||||
|
||||
#define ql_first(a_head) ((a_head)->qlh_first)
|
||||
|
||||
#define ql_last(a_head, a_field) \
|
||||
((ql_first(a_head) != NULL) \
|
||||
? qr_prev(ql_first(a_head), a_field) : NULL)
|
||||
|
||||
#define ql_next(a_head, a_elm, a_field) \
|
||||
((ql_last(a_head, a_field) != (a_elm)) \
|
||||
? qr_next((a_elm), a_field) : NULL)
|
||||
|
||||
#define ql_prev(a_head, a_elm, a_field) \
|
||||
((ql_first(a_head) != (a_elm)) ? qr_prev((a_elm), a_field) \
|
||||
: NULL)
|
||||
|
||||
#define ql_before_insert(a_head, a_qlelm, a_elm, a_field) do { \
|
||||
qr_before_insert((a_qlelm), (a_elm), a_field); \
|
||||
if (ql_first(a_head) == (a_qlelm)) { \
|
||||
ql_first(a_head) = (a_elm); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ql_after_insert(a_qlelm, a_elm, a_field) \
|
||||
qr_after_insert((a_qlelm), (a_elm), a_field)
|
||||
|
||||
#define ql_head_insert(a_head, a_elm, a_field) do { \
|
||||
if (ql_first(a_head) != NULL) { \
|
||||
qr_before_insert(ql_first(a_head), (a_elm), a_field); \
|
||||
} \
|
||||
ql_first(a_head) = (a_elm); \
|
||||
} while (0)
|
||||
|
||||
#define ql_tail_insert(a_head, a_elm, a_field) do { \
|
||||
if (ql_first(a_head) != NULL) { \
|
||||
qr_before_insert(ql_first(a_head), (a_elm), a_field); \
|
||||
} \
|
||||
ql_first(a_head) = qr_next((a_elm), a_field); \
|
||||
} while (0)
|
||||
|
||||
#define ql_remove(a_head, a_elm, a_field) do { \
|
||||
if (ql_first(a_head) == (a_elm)) { \
|
||||
ql_first(a_head) = qr_next(ql_first(a_head), a_field); \
|
||||
} \
|
||||
if (ql_first(a_head) != (a_elm)) { \
|
||||
qr_remove((a_elm), a_field); \
|
||||
} else { \
|
||||
ql_first(a_head) = NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define ql_head_remove(a_head, a_type, a_field) do { \
|
||||
a_type *t = ql_first(a_head); \
|
||||
ql_remove((a_head), t, a_field); \
|
||||
} while (0)
|
||||
|
||||
#define ql_tail_remove(a_head, a_type, a_field) do { \
|
||||
a_type *t = ql_last(a_head, a_field); \
|
||||
ql_remove((a_head), t, a_field); \
|
||||
} while (0)
|
||||
|
||||
#define ql_foreach(a_var, a_head, a_field) \
|
||||
qr_foreach((a_var), ql_first(a_head), a_field)
|
||||
|
||||
#define ql_reverse_foreach(a_var, a_head, a_field) \
|
||||
qr_reverse_foreach((a_var), ql_first(a_head), a_field)
|
98
apilibs/kexbasen/kernel32/jemalloc/qr.h
Executable file
98
apilibs/kexbasen/kernel32/jemalloc/qr.h
Executable file
@ -0,0 +1,98 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2002 Jason Evans <jasone@canonware.com>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice(s), this list of conditions and the following disclaimer
|
||||
* unmodified other than the allowable addition of one or more
|
||||
* copyright notices.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice(s), this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/* Ring definitions. */
|
||||
#define qr(a_type) \
|
||||
struct { \
|
||||
a_type *qre_next; \
|
||||
a_type *qre_prev; \
|
||||
}
|
||||
|
||||
/* Ring functions. */
|
||||
#define qr_new(a_qr, a_field) do { \
|
||||
(a_qr)->a_field.qre_next = (a_qr); \
|
||||
(a_qr)->a_field.qre_prev = (a_qr); \
|
||||
} while (0)
|
||||
|
||||
#define qr_next(a_qr, a_field) ((a_qr)->a_field.qre_next)
|
||||
|
||||
#define qr_prev(a_qr, a_field) ((a_qr)->a_field.qre_prev)
|
||||
|
||||
#define qr_before_insert(a_qrelm, a_qr, a_field) do { \
|
||||
(a_qr)->a_field.qre_prev = (a_qrelm)->a_field.qre_prev; \
|
||||
(a_qr)->a_field.qre_next = (a_qrelm); \
|
||||
(a_qr)->a_field.qre_prev->a_field.qre_next = (a_qr); \
|
||||
(a_qrelm)->a_field.qre_prev = (a_qr); \
|
||||
} while (0)
|
||||
|
||||
#define qr_after_insert(a_qrelm, a_qr, a_field) \
|
||||
do \
|
||||
{ \
|
||||
(a_qr)->a_field.qre_next = (a_qrelm)->a_field.qre_next; \
|
||||
(a_qr)->a_field.qre_prev = (a_qrelm); \
|
||||
(a_qr)->a_field.qre_next->a_field.qre_prev = (a_qr); \
|
||||
(a_qrelm)->a_field.qre_next = (a_qr); \
|
||||
} while (0)
|
||||
|
||||
#define qr_meld(a_qr_a, a_qr_b, a_field) do { \
|
||||
void *t; \
|
||||
(a_qr_a)->a_field.qre_prev->a_field.qre_next = (a_qr_b); \
|
||||
(a_qr_b)->a_field.qre_prev->a_field.qre_next = (a_qr_a); \
|
||||
t = (a_qr_a)->a_field.qre_prev; \
|
||||
(a_qr_a)->a_field.qre_prev = (a_qr_b)->a_field.qre_prev; \
|
||||
(a_qr_b)->a_field.qre_prev = t; \
|
||||
} while (0)
|
||||
|
||||
/* qr_meld() and qr_split() are functionally equivalent, so there's no need to
|
||||
* have two copies of the code. */
|
||||
#define qr_split(a_qr_a, a_qr_b, a_field) \
|
||||
qr_meld((a_qr_a), (a_qr_b), a_field)
|
||||
|
||||
#define qr_remove(a_qr, a_field) do { \
|
||||
(a_qr)->a_field.qre_prev->a_field.qre_next \
|
||||
= (a_qr)->a_field.qre_next; \
|
||||
(a_qr)->a_field.qre_next->a_field.qre_prev \
|
||||
= (a_qr)->a_field.qre_prev; \
|
||||
(a_qr)->a_field.qre_next = (a_qr); \
|
||||
(a_qr)->a_field.qre_prev = (a_qr); \
|
||||
} while (0)
|
||||
|
||||
#define qr_foreach(var, a_qr, a_field) \
|
||||
for ((var) = (a_qr); \
|
||||
(var) != NULL; \
|
||||
(var) = (((var)->a_field.qre_next != (a_qr)) \
|
||||
? (var)->a_field.qre_next : NULL))
|
||||
|
||||
#define qr_reverse_foreach(var, a_qr, a_field) \
|
||||
for ((var) = ((a_qr) != NULL) ? qr_prev(a_qr, a_field) : NULL; \
|
||||
(var) != NULL; \
|
||||
(var) = (((var) != (a_qr)) \
|
||||
? (var)->a_field.qre_prev : NULL))
|
982
apilibs/kexbasen/kernel32/jemalloc/rb.h
Executable file
982
apilibs/kexbasen/kernel32/jemalloc/rb.h
Executable file
@ -0,0 +1,982 @@
|
||||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2008 Jason Evans <jasone@FreeBSD.org>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice(s), this list of conditions and the following disclaimer
|
||||
* unmodified other than the allowable addition of one or more
|
||||
* copyright notices.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice(s), this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
******************************************************************************
|
||||
*
|
||||
* cpp macro implementation of left-leaning red-black trees.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* (Optional.)
|
||||
* #define SIZEOF_PTR ...
|
||||
* #define SIZEOF_PTR_2POW ...
|
||||
* #define RB_NO_C99_VARARRAYS
|
||||
*
|
||||
* (Optional, see assert(3).)
|
||||
* #define NDEBUG
|
||||
*
|
||||
* (Required.)
|
||||
* #include <assert.h>
|
||||
* #include <rb.h>
|
||||
* ...
|
||||
*
|
||||
* All operations are done non-recursively. Parent pointers are not used, and
|
||||
* color bits are stored in the least significant bit of right-child pointers,
|
||||
* thus making node linkage as compact as is possible for red-black trees.
|
||||
*
|
||||
* Some macros use a comparison function pointer, which is expected to have the
|
||||
* following prototype:
|
||||
*
|
||||
* int (a_cmp *)(a_type *a_node, a_type *a_other);
|
||||
* ^^^^^^
|
||||
* or a_key
|
||||
*
|
||||
* Interpretation of comparision function return values:
|
||||
*
|
||||
* -1 : a_node < a_other
|
||||
* 0 : a_node == a_other
|
||||
* 1 : a_node > a_other
|
||||
*
|
||||
* In all cases, the a_node or a_key macro argument is the first argument to the
|
||||
* comparison function, which makes it possible to write comparison functions
|
||||
* that treat the first argument specially.
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef RB_H_
|
||||
#define RB_H_
|
||||
|
||||
#if 0
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD: head/lib/libc/stdlib/rb.h 178995 2008-05-14 18:33:13Z jasone $");
|
||||
#endif
|
||||
|
||||
/* Node structure. */
|
||||
#define rb_node(a_type) \
|
||||
struct { \
|
||||
a_type *rbn_left; \
|
||||
a_type *rbn_right_red; \
|
||||
}
|
||||
|
||||
/* Root structure. */
|
||||
#define rb_tree(a_type) \
|
||||
struct { \
|
||||
a_type *rbt_root; \
|
||||
a_type rbt_nil; \
|
||||
}
|
||||
|
||||
/* Left accessors. */
|
||||
#define rbp_left_get(a_type, a_field, a_node) \
|
||||
((a_node)->a_field.rbn_left)
|
||||
#define rbp_left_set(a_type, a_field, a_node, a_left) do { \
|
||||
(a_node)->a_field.rbn_left = a_left; \
|
||||
} while (0)
|
||||
|
||||
/* Right accessors. */
|
||||
#define rbp_right_get(a_type, a_field, a_node) \
|
||||
((a_type *) (((intptr_t) (a_node)->a_field.rbn_right_red) \
|
||||
& ((ssize_t)-2)))
|
||||
#define rbp_right_set(a_type, a_field, a_node, a_right) do { \
|
||||
(a_node)->a_field.rbn_right_red = (a_type *) (((uintptr_t) a_right) \
|
||||
| (((uintptr_t) (a_node)->a_field.rbn_right_red) & ((size_t)1))); \
|
||||
} while (0)
|
||||
|
||||
/* Color accessors. */
|
||||
#define rbp_red_get(a_type, a_field, a_node) \
|
||||
((bool) (((uintptr_t) (a_node)->a_field.rbn_right_red) \
|
||||
& ((size_t)1)))
|
||||
#define rbp_color_set(a_type, a_field, a_node, a_red) do { \
|
||||
(a_node)->a_field.rbn_right_red = (a_type *) ((((intptr_t) \
|
||||
(a_node)->a_field.rbn_right_red) & ((ssize_t)-2)) \
|
||||
| ((ssize_t)a_red)); \
|
||||
} while (0)
|
||||
#define rbp_red_set(a_type, a_field, a_node) do { \
|
||||
(a_node)->a_field.rbn_right_red = (a_type *) (((uintptr_t) \
|
||||
(a_node)->a_field.rbn_right_red) | ((size_t)1)); \
|
||||
} while (0)
|
||||
#define rbp_black_set(a_type, a_field, a_node) do { \
|
||||
(a_node)->a_field.rbn_right_red = (a_type *) (((intptr_t) \
|
||||
(a_node)->a_field.rbn_right_red) & ((ssize_t)-2)); \
|
||||
} while (0)
|
||||
|
||||
/* Node initializer. */
|
||||
#define rbp_node_new(a_type, a_field, a_tree, a_node) do { \
|
||||
rbp_left_set(a_type, a_field, (a_node), &(a_tree)->rbt_nil); \
|
||||
rbp_right_set(a_type, a_field, (a_node), &(a_tree)->rbt_nil); \
|
||||
rbp_red_set(a_type, a_field, (a_node)); \
|
||||
} while (0)
|
||||
|
||||
/* Tree initializer. */
|
||||
#define rb_new(a_type, a_field, a_tree) do { \
|
||||
(a_tree)->rbt_root = &(a_tree)->rbt_nil; \
|
||||
rbp_node_new(a_type, a_field, a_tree, &(a_tree)->rbt_nil); \
|
||||
rbp_black_set(a_type, a_field, &(a_tree)->rbt_nil); \
|
||||
} while (0)
|
||||
|
||||
/* Tree operations. */
|
||||
#define rbp_black_height(a_type, a_field, a_tree, r_height) do { \
|
||||
a_type *rbp_bh_t; \
|
||||
for (rbp_bh_t = (a_tree)->rbt_root, (r_height) = 0; \
|
||||
rbp_bh_t != &(a_tree)->rbt_nil; \
|
||||
rbp_bh_t = rbp_left_get(a_type, a_field, rbp_bh_t)) { \
|
||||
if (rbp_red_get(a_type, a_field, rbp_bh_t) == false) { \
|
||||
(r_height)++; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define rbp_first(a_type, a_field, a_tree, a_root, r_node) do { \
|
||||
for ((r_node) = (a_root); \
|
||||
rbp_left_get(a_type, a_field, (r_node)) != &(a_tree)->rbt_nil; \
|
||||
(r_node) = rbp_left_get(a_type, a_field, (r_node))) { \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define rbp_last(a_type, a_field, a_tree, a_root, r_node) do { \
|
||||
for ((r_node) = (a_root); \
|
||||
rbp_right_get(a_type, a_field, (r_node)) != &(a_tree)->rbt_nil; \
|
||||
(r_node) = rbp_right_get(a_type, a_field, (r_node))) { \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define rbp_next(a_type, a_field, a_cmp, a_tree, a_node, r_node) do { \
|
||||
if (rbp_right_get(a_type, a_field, (a_node)) \
|
||||
!= &(a_tree)->rbt_nil) { \
|
||||
rbp_first(a_type, a_field, a_tree, rbp_right_get(a_type, \
|
||||
a_field, (a_node)), (r_node)); \
|
||||
} else { \
|
||||
a_type *rbp_n_t = (a_tree)->rbt_root; \
|
||||
assert(rbp_n_t != &(a_tree)->rbt_nil); \
|
||||
(r_node) = &(a_tree)->rbt_nil; \
|
||||
while (true) { \
|
||||
int rbp_n_cmp = (a_cmp)((a_node), rbp_n_t); \
|
||||
if (rbp_n_cmp < 0) { \
|
||||
(r_node) = rbp_n_t; \
|
||||
rbp_n_t = rbp_left_get(a_type, a_field, rbp_n_t); \
|
||||
} else if (rbp_n_cmp > 0) { \
|
||||
rbp_n_t = rbp_right_get(a_type, a_field, rbp_n_t); \
|
||||
} else { \
|
||||
break; \
|
||||
} \
|
||||
assert(rbp_n_t != &(a_tree)->rbt_nil); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define rbp_prev(a_type, a_field, a_cmp, a_tree, a_node, r_node) do { \
|
||||
if (rbp_left_get(a_type, a_field, (a_node)) != &(a_tree)->rbt_nil) {\
|
||||
rbp_last(a_type, a_field, a_tree, rbp_left_get(a_type, \
|
||||
a_field, (a_node)), (r_node)); \
|
||||
} else { \
|
||||
a_type *rbp_p_t = (a_tree)->rbt_root; \
|
||||
assert(rbp_p_t != &(a_tree)->rbt_nil); \
|
||||
(r_node) = &(a_tree)->rbt_nil; \
|
||||
while (true) { \
|
||||
int rbp_p_cmp = (a_cmp)((a_node), rbp_p_t); \
|
||||
if (rbp_p_cmp < 0) { \
|
||||
rbp_p_t = rbp_left_get(a_type, a_field, rbp_p_t); \
|
||||
} else if (rbp_p_cmp > 0) { \
|
||||
(r_node) = rbp_p_t; \
|
||||
rbp_p_t = rbp_right_get(a_type, a_field, rbp_p_t); \
|
||||
} else { \
|
||||
break; \
|
||||
} \
|
||||
assert(rbp_p_t != &(a_tree)->rbt_nil); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define rb_first(a_type, a_field, a_tree, r_node) do { \
|
||||
rbp_first(a_type, a_field, a_tree, (a_tree)->rbt_root, (r_node)); \
|
||||
if ((r_node) == &(a_tree)->rbt_nil) { \
|
||||
(r_node) = NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define rb_last(a_type, a_field, a_tree, r_node) do { \
|
||||
rbp_last(a_type, a_field, a_tree, (a_tree)->rbt_root, r_node); \
|
||||
if ((r_node) == &(a_tree)->rbt_nil) { \
|
||||
(r_node) = NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define rb_next(a_type, a_field, a_cmp, a_tree, a_node, r_node) do { \
|
||||
rbp_next(a_type, a_field, a_cmp, a_tree, (a_node), (r_node)); \
|
||||
if ((r_node) == &(a_tree)->rbt_nil) { \
|
||||
(r_node) = NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define rb_prev(a_type, a_field, a_cmp, a_tree, a_node, r_node) do { \
|
||||
rbp_prev(a_type, a_field, a_cmp, a_tree, (a_node), (r_node)); \
|
||||
if ((r_node) == &(a_tree)->rbt_nil) { \
|
||||
(r_node) = NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define rb_search(a_type, a_field, a_cmp, a_tree, a_key, r_node) do { \
|
||||
int rbp_se_cmp; \
|
||||
(r_node) = (a_tree)->rbt_root; \
|
||||
while ((r_node) != &(a_tree)->rbt_nil \
|
||||
&& (rbp_se_cmp = (a_cmp)((a_key), (r_node))) != 0) { \
|
||||
if (rbp_se_cmp < 0) { \
|
||||
(r_node) = rbp_left_get(a_type, a_field, (r_node)); \
|
||||
} else { \
|
||||
(r_node) = rbp_right_get(a_type, a_field, (r_node)); \
|
||||
} \
|
||||
} \
|
||||
if ((r_node) == &(a_tree)->rbt_nil) { \
|
||||
(r_node) = NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Find a match if it exists. Otherwise, find the next greater node, if one
|
||||
* exists.
|
||||
*/
|
||||
#define rb_nsearch(a_type, a_field, a_cmp, a_tree, a_key, r_node) do { \
|
||||
a_type *rbp_ns_t = (a_tree)->rbt_root; \
|
||||
(r_node) = NULL; \
|
||||
while (rbp_ns_t != &(a_tree)->rbt_nil) { \
|
||||
int rbp_ns_cmp = (a_cmp)((a_key), rbp_ns_t); \
|
||||
if (rbp_ns_cmp < 0) { \
|
||||
(r_node) = rbp_ns_t; \
|
||||
rbp_ns_t = rbp_left_get(a_type, a_field, rbp_ns_t); \
|
||||
} else if (rbp_ns_cmp > 0) { \
|
||||
rbp_ns_t = rbp_right_get(a_type, a_field, rbp_ns_t); \
|
||||
} else { \
|
||||
(r_node) = rbp_ns_t; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Find a match if it exists. Otherwise, find the previous lesser node, if one
|
||||
* exists.
|
||||
*/
|
||||
#define rb_psearch(a_type, a_field, a_cmp, a_tree, a_key, r_node) do { \
|
||||
a_type *rbp_ps_t = (a_tree)->rbt_root; \
|
||||
(r_node) = NULL; \
|
||||
while (rbp_ps_t != &(a_tree)->rbt_nil) { \
|
||||
int rbp_ps_cmp = (a_cmp)((a_key), rbp_ps_t); \
|
||||
if (rbp_ps_cmp < 0) { \
|
||||
rbp_ps_t = rbp_left_get(a_type, a_field, rbp_ps_t); \
|
||||
} else if (rbp_ps_cmp > 0) { \
|
||||
(r_node) = rbp_ps_t; \
|
||||
rbp_ps_t = rbp_right_get(a_type, a_field, rbp_ps_t); \
|
||||
} else { \
|
||||
(r_node) = rbp_ps_t; \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define rbp_rotate_left(a_type, a_field, a_node, r_node) do { \
|
||||
(r_node) = rbp_right_get(a_type, a_field, (a_node)); \
|
||||
rbp_right_set(a_type, a_field, (a_node), \
|
||||
rbp_left_get(a_type, a_field, (r_node))); \
|
||||
rbp_left_set(a_type, a_field, (r_node), (a_node)); \
|
||||
} while (0)
|
||||
|
||||
#define rbp_rotate_right(a_type, a_field, a_node, r_node) do { \
|
||||
(r_node) = rbp_left_get(a_type, a_field, (a_node)); \
|
||||
rbp_left_set(a_type, a_field, (a_node), \
|
||||
rbp_right_get(a_type, a_field, (r_node))); \
|
||||
rbp_right_set(a_type, a_field, (r_node), (a_node)); \
|
||||
} while (0)
|
||||
|
||||
#define rbp_lean_left(a_type, a_field, a_node, r_node) do { \
|
||||
bool rbp_ll_red; \
|
||||
rbp_rotate_left(a_type, a_field, (a_node), (r_node)); \
|
||||
rbp_ll_red = rbp_red_get(a_type, a_field, (a_node)); \
|
||||
rbp_color_set(a_type, a_field, (r_node), rbp_ll_red); \
|
||||
rbp_red_set(a_type, a_field, (a_node)); \
|
||||
} while (0)
|
||||
|
||||
#define rbp_lean_right(a_type, a_field, a_node, r_node) do { \
|
||||
bool rbp_lr_red; \
|
||||
rbp_rotate_right(a_type, a_field, (a_node), (r_node)); \
|
||||
rbp_lr_red = rbp_red_get(a_type, a_field, (a_node)); \
|
||||
rbp_color_set(a_type, a_field, (r_node), rbp_lr_red); \
|
||||
rbp_red_set(a_type, a_field, (a_node)); \
|
||||
} while (0)
|
||||
|
||||
#define rbp_move_red_left(a_type, a_field, a_node, r_node) do { \
|
||||
a_type *rbp_mrl_t, *rbp_mrl_u; \
|
||||
rbp_mrl_t = rbp_left_get(a_type, a_field, (a_node)); \
|
||||
rbp_red_set(a_type, a_field, rbp_mrl_t); \
|
||||
rbp_mrl_t = rbp_right_get(a_type, a_field, (a_node)); \
|
||||
rbp_mrl_u = rbp_left_get(a_type, a_field, rbp_mrl_t); \
|
||||
if (rbp_red_get(a_type, a_field, rbp_mrl_u)) { \
|
||||
rbp_rotate_right(a_type, a_field, rbp_mrl_t, rbp_mrl_u); \
|
||||
rbp_right_set(a_type, a_field, (a_node), rbp_mrl_u); \
|
||||
rbp_rotate_left(a_type, a_field, (a_node), (r_node)); \
|
||||
rbp_mrl_t = rbp_right_get(a_type, a_field, (a_node)); \
|
||||
if (rbp_red_get(a_type, a_field, rbp_mrl_t)) { \
|
||||
rbp_black_set(a_type, a_field, rbp_mrl_t); \
|
||||
rbp_red_set(a_type, a_field, (a_node)); \
|
||||
rbp_rotate_left(a_type, a_field, (a_node), rbp_mrl_t); \
|
||||
rbp_left_set(a_type, a_field, (r_node), rbp_mrl_t); \
|
||||
} else { \
|
||||
rbp_black_set(a_type, a_field, (a_node)); \
|
||||
} \
|
||||
} else { \
|
||||
rbp_red_set(a_type, a_field, (a_node)); \
|
||||
rbp_rotate_left(a_type, a_field, (a_node), (r_node)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define rbp_move_red_right(a_type, a_field, a_node, r_node) do { \
|
||||
a_type *rbp_mrr_t; \
|
||||
rbp_mrr_t = rbp_left_get(a_type, a_field, (a_node)); \
|
||||
if (rbp_red_get(a_type, a_field, rbp_mrr_t)) { \
|
||||
a_type *rbp_mrr_u, *rbp_mrr_v; \
|
||||
rbp_mrr_u = rbp_right_get(a_type, a_field, rbp_mrr_t); \
|
||||
rbp_mrr_v = rbp_left_get(a_type, a_field, rbp_mrr_u); \
|
||||
if (rbp_red_get(a_type, a_field, rbp_mrr_v)) { \
|
||||
rbp_color_set(a_type, a_field, rbp_mrr_u, \
|
||||
rbp_red_get(a_type, a_field, (a_node))); \
|
||||
rbp_black_set(a_type, a_field, rbp_mrr_v); \
|
||||
rbp_rotate_left(a_type, a_field, rbp_mrr_t, rbp_mrr_u); \
|
||||
rbp_left_set(a_type, a_field, (a_node), rbp_mrr_u); \
|
||||
rbp_rotate_right(a_type, a_field, (a_node), (r_node)); \
|
||||
rbp_rotate_left(a_type, a_field, (a_node), rbp_mrr_t); \
|
||||
rbp_right_set(a_type, a_field, (r_node), rbp_mrr_t); \
|
||||
} else { \
|
||||
rbp_color_set(a_type, a_field, rbp_mrr_t, \
|
||||
rbp_red_get(a_type, a_field, (a_node))); \
|
||||
rbp_red_set(a_type, a_field, rbp_mrr_u); \
|
||||
rbp_rotate_right(a_type, a_field, (a_node), (r_node)); \
|
||||
rbp_rotate_left(a_type, a_field, (a_node), rbp_mrr_t); \
|
||||
rbp_right_set(a_type, a_field, (r_node), rbp_mrr_t); \
|
||||
} \
|
||||
rbp_red_set(a_type, a_field, (a_node)); \
|
||||
} else { \
|
||||
rbp_red_set(a_type, a_field, rbp_mrr_t); \
|
||||
rbp_mrr_t = rbp_left_get(a_type, a_field, rbp_mrr_t); \
|
||||
if (rbp_red_get(a_type, a_field, rbp_mrr_t)) { \
|
||||
rbp_black_set(a_type, a_field, rbp_mrr_t); \
|
||||
rbp_rotate_right(a_type, a_field, (a_node), (r_node)); \
|
||||
rbp_rotate_left(a_type, a_field, (a_node), rbp_mrr_t); \
|
||||
rbp_right_set(a_type, a_field, (r_node), rbp_mrr_t); \
|
||||
} else { \
|
||||
rbp_rotate_left(a_type, a_field, (a_node), (r_node)); \
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define rb_insert(a_type, a_field, a_cmp, a_tree, a_node) do { \
|
||||
a_type rbp_i_s; \
|
||||
a_type *rbp_i_g, *rbp_i_p, *rbp_i_c, *rbp_i_t, *rbp_i_u; \
|
||||
int rbp_i_cmp = 0; \
|
||||
rbp_i_g = &(a_tree)->rbt_nil; \
|
||||
rbp_left_set(a_type, a_field, &rbp_i_s, (a_tree)->rbt_root); \
|
||||
rbp_right_set(a_type, a_field, &rbp_i_s, &(a_tree)->rbt_nil); \
|
||||
rbp_black_set(a_type, a_field, &rbp_i_s); \
|
||||
rbp_i_p = &rbp_i_s; \
|
||||
rbp_i_c = (a_tree)->rbt_root; \
|
||||
/* Iteratively search down the tree for the insertion point, */\
|
||||
/* splitting 4-nodes as they are encountered. At the end of each */\
|
||||
/* iteration, rbp_i_g->rbp_i_p->rbp_i_c is a 3-level path down */\
|
||||
/* the tree, assuming a sufficiently deep tree. */\
|
||||
while (rbp_i_c != &(a_tree)->rbt_nil) { \
|
||||
rbp_i_t = rbp_left_get(a_type, a_field, rbp_i_c); \
|
||||
rbp_i_u = rbp_left_get(a_type, a_field, rbp_i_t); \
|
||||
if (rbp_red_get(a_type, a_field, rbp_i_t) \
|
||||
&& rbp_red_get(a_type, a_field, rbp_i_u)) { \
|
||||
/* rbp_i_c is the top of a logical 4-node, so split it. */\
|
||||
/* This iteration does not move down the tree, due to the */\
|
||||
/* disruptiveness of node splitting. */\
|
||||
/* */\
|
||||
/* Rotate right. */\
|
||||
rbp_rotate_right(a_type, a_field, rbp_i_c, rbp_i_t); \
|
||||
/* Pass red links up one level. */\
|
||||
rbp_i_u = rbp_left_get(a_type, a_field, rbp_i_t); \
|
||||
rbp_black_set(a_type, a_field, rbp_i_u); \
|
||||
if (rbp_left_get(a_type, a_field, rbp_i_p) == rbp_i_c) { \
|
||||
rbp_left_set(a_type, a_field, rbp_i_p, rbp_i_t); \
|
||||
rbp_i_c = rbp_i_t; \
|
||||
} else { \
|
||||
/* rbp_i_c was the right child of rbp_i_p, so rotate */\
|
||||
/* left in order to maintain the left-leaning */\
|
||||
/* invariant. */\
|
||||
assert(rbp_right_get(a_type, a_field, rbp_i_p) \
|
||||
== rbp_i_c); \
|
||||
rbp_right_set(a_type, a_field, rbp_i_p, rbp_i_t); \
|
||||
rbp_lean_left(a_type, a_field, rbp_i_p, rbp_i_u); \
|
||||
if (rbp_left_get(a_type, a_field, rbp_i_g) == rbp_i_p) {\
|
||||
rbp_left_set(a_type, a_field, rbp_i_g, rbp_i_u); \
|
||||
} else { \
|
||||
assert(rbp_right_get(a_type, a_field, rbp_i_g) \
|
||||
== rbp_i_p); \
|
||||
rbp_right_set(a_type, a_field, rbp_i_g, rbp_i_u); \
|
||||
} \
|
||||
rbp_i_p = rbp_i_u; \
|
||||
rbp_i_cmp = (a_cmp)((a_node), rbp_i_p); \
|
||||
if (rbp_i_cmp < 0) { \
|
||||
rbp_i_c = rbp_left_get(a_type, a_field, rbp_i_p); \
|
||||
} else { \
|
||||
assert(rbp_i_cmp > 0); \
|
||||
rbp_i_c = rbp_right_get(a_type, a_field, rbp_i_p); \
|
||||
} \
|
||||
continue; \
|
||||
} \
|
||||
} \
|
||||
rbp_i_g = rbp_i_p; \
|
||||
rbp_i_p = rbp_i_c; \
|
||||
rbp_i_cmp = (a_cmp)((a_node), rbp_i_c); \
|
||||
if (rbp_i_cmp < 0) { \
|
||||
rbp_i_c = rbp_left_get(a_type, a_field, rbp_i_c); \
|
||||
} else { \
|
||||
assert(rbp_i_cmp > 0); \
|
||||
rbp_i_c = rbp_right_get(a_type, a_field, rbp_i_c); \
|
||||
} \
|
||||
} \
|
||||
/* rbp_i_p now refers to the node under which to insert. */\
|
||||
rbp_node_new(a_type, a_field, a_tree, (a_node)); \
|
||||
if (rbp_i_cmp > 0) { \
|
||||
rbp_right_set(a_type, a_field, rbp_i_p, (a_node)); \
|
||||
rbp_lean_left(a_type, a_field, rbp_i_p, rbp_i_t); \
|
||||
if (rbp_left_get(a_type, a_field, rbp_i_g) == rbp_i_p) { \
|
||||
rbp_left_set(a_type, a_field, rbp_i_g, rbp_i_t); \
|
||||
} else if (rbp_right_get(a_type, a_field, rbp_i_g) == rbp_i_p) {\
|
||||
rbp_right_set(a_type, a_field, rbp_i_g, rbp_i_t); \
|
||||
} \
|
||||
} else { \
|
||||
rbp_left_set(a_type, a_field, rbp_i_p, (a_node)); \
|
||||
} \
|
||||
/* Update the root and make sure that it is black. */\
|
||||
(a_tree)->rbt_root = rbp_left_get(a_type, a_field, &rbp_i_s); \
|
||||
rbp_black_set(a_type, a_field, (a_tree)->rbt_root); \
|
||||
} while (0)
|
||||
|
||||
#define rb_remove(a_type, a_field, a_cmp, a_tree, a_node) do { \
|
||||
a_type rbp_r_s; \
|
||||
a_type *rbp_r_p, *rbp_r_c, *rbp_r_xp, *rbp_r_t, *rbp_r_u; \
|
||||
int rbp_r_cmp; \
|
||||
rbp_left_set(a_type, a_field, &rbp_r_s, (a_tree)->rbt_root); \
|
||||
rbp_right_set(a_type, a_field, &rbp_r_s, &(a_tree)->rbt_nil); \
|
||||
rbp_black_set(a_type, a_field, &rbp_r_s); \
|
||||
rbp_r_p = &rbp_r_s; \
|
||||
rbp_r_c = (a_tree)->rbt_root; \
|
||||
rbp_r_xp = &(a_tree)->rbt_nil; \
|
||||
/* Iterate down the tree, but always transform 2-nodes to 3- or */\
|
||||
/* 4-nodes in order to maintain the invariant that the current */\
|
||||
/* node is not a 2-node. This allows simple deletion once a leaf */\
|
||||
/* is reached. Handle the root specially though, since there may */\
|
||||
/* be no way to convert it from a 2-node to a 3-node. */\
|
||||
rbp_r_cmp = (a_cmp)((a_node), rbp_r_c); \
|
||||
if (rbp_r_cmp < 0) { \
|
||||
rbp_r_t = rbp_left_get(a_type, a_field, rbp_r_c); \
|
||||
rbp_r_u = rbp_left_get(a_type, a_field, rbp_r_t); \
|
||||
if (rbp_red_get(a_type, a_field, rbp_r_t) == false \
|
||||
&& rbp_red_get(a_type, a_field, rbp_r_u) == false) { \
|
||||
/* Apply standard transform to prepare for left move. */\
|
||||
rbp_move_red_left(a_type, a_field, rbp_r_c, rbp_r_t); \
|
||||
rbp_black_set(a_type, a_field, rbp_r_t); \
|
||||
rbp_left_set(a_type, a_field, rbp_r_p, rbp_r_t); \
|
||||
rbp_r_c = rbp_r_t; \
|
||||
} else { \
|
||||
/* Move left. */\
|
||||
rbp_r_p = rbp_r_c; \
|
||||
rbp_r_c = rbp_left_get(a_type, a_field, rbp_r_c); \
|
||||
} \
|
||||
} else { \
|
||||
if (rbp_r_cmp == 0) { \
|
||||
assert((a_node) == rbp_r_c); \
|
||||
if (rbp_right_get(a_type, a_field, rbp_r_c) \
|
||||
== &(a_tree)->rbt_nil) { \
|
||||
/* Delete root node (which is also a leaf node). */\
|
||||
if (rbp_left_get(a_type, a_field, rbp_r_c) \
|
||||
!= &(a_tree)->rbt_nil) { \
|
||||
rbp_lean_right(a_type, a_field, rbp_r_c, rbp_r_t); \
|
||||
rbp_right_set(a_type, a_field, rbp_r_t, \
|
||||
&(a_tree)->rbt_nil); \
|
||||
} else { \
|
||||
rbp_r_t = &(a_tree)->rbt_nil; \
|
||||
} \
|
||||
rbp_left_set(a_type, a_field, rbp_r_p, rbp_r_t); \
|
||||
} else { \
|
||||
/* This is the node we want to delete, but we will */\
|
||||
/* instead swap it with its successor and delete the */\
|
||||
/* successor. Record enough information to do the */\
|
||||
/* swap later. rbp_r_xp is the a_node's parent. */\
|
||||
rbp_r_xp = rbp_r_p; \
|
||||
rbp_r_cmp = 1; /* Note that deletion is incomplete. */\
|
||||
} \
|
||||
} \
|
||||
if (rbp_r_cmp == 1) { \
|
||||
if (rbp_red_get(a_type, a_field, rbp_left_get(a_type, \
|
||||
a_field, rbp_right_get(a_type, a_field, rbp_r_c))) \
|
||||
== false) { \
|
||||
rbp_r_t = rbp_left_get(a_type, a_field, rbp_r_c); \
|
||||
if (rbp_red_get(a_type, a_field, rbp_r_t)) { \
|
||||
/* Standard transform. */\
|
||||
rbp_move_red_right(a_type, a_field, rbp_r_c, \
|
||||
rbp_r_t); \
|
||||
} else { \
|
||||
/* Root-specific transform. */\
|
||||
rbp_red_set(a_type, a_field, rbp_r_c); \
|
||||
rbp_r_u = rbp_left_get(a_type, a_field, rbp_r_t); \
|
||||
if (rbp_red_get(a_type, a_field, rbp_r_u)) { \
|
||||
rbp_black_set(a_type, a_field, rbp_r_u); \
|
||||
rbp_rotate_right(a_type, a_field, rbp_r_c, \
|
||||
rbp_r_t); \
|
||||
rbp_rotate_left(a_type, a_field, rbp_r_c, \
|
||||
rbp_r_u); \
|
||||
rbp_right_set(a_type, a_field, rbp_r_t, \
|
||||
rbp_r_u); \
|
||||
} else { \
|
||||
rbp_red_set(a_type, a_field, rbp_r_t); \
|
||||
rbp_rotate_left(a_type, a_field, rbp_r_c, \
|
||||
rbp_r_t); \
|
||||
} \
|
||||
} \
|
||||
rbp_left_set(a_type, a_field, rbp_r_p, rbp_r_t); \
|
||||
rbp_r_c = rbp_r_t; \
|
||||
} else { \
|
||||
/* Move right. */\
|
||||
rbp_r_p = rbp_r_c; \
|
||||
rbp_r_c = rbp_right_get(a_type, a_field, rbp_r_c); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
if (rbp_r_cmp != 0) { \
|
||||
while (true) { \
|
||||
assert(rbp_r_p != &(a_tree)->rbt_nil); \
|
||||
rbp_r_cmp = (a_cmp)((a_node), rbp_r_c); \
|
||||
if (rbp_r_cmp < 0) { \
|
||||
rbp_r_t = rbp_left_get(a_type, a_field, rbp_r_c); \
|
||||
if (rbp_r_t == &(a_tree)->rbt_nil) { \
|
||||
/* rbp_r_c now refers to the successor node to */\
|
||||
/* relocate, and rbp_r_xp/a_node refer to the */\
|
||||
/* context for the relocation. */\
|
||||
if (rbp_left_get(a_type, a_field, rbp_r_xp) \
|
||||
== (a_node)) { \
|
||||
rbp_left_set(a_type, a_field, rbp_r_xp, \
|
||||
rbp_r_c); \
|
||||
} else { \
|
||||
assert(rbp_right_get(a_type, a_field, \
|
||||
rbp_r_xp) == (a_node)); \
|
||||
rbp_right_set(a_type, a_field, rbp_r_xp, \
|
||||
rbp_r_c); \
|
||||
} \
|
||||
rbp_left_set(a_type, a_field, rbp_r_c, \
|
||||
rbp_left_get(a_type, a_field, (a_node))); \
|
||||
rbp_right_set(a_type, a_field, rbp_r_c, \
|
||||
rbp_right_get(a_type, a_field, (a_node))); \
|
||||
rbp_color_set(a_type, a_field, rbp_r_c, \
|
||||
rbp_red_get(a_type, a_field, (a_node))); \
|
||||
if (rbp_left_get(a_type, a_field, rbp_r_p) \
|
||||
== rbp_r_c) { \
|
||||
rbp_left_set(a_type, a_field, rbp_r_p, \
|
||||
&(a_tree)->rbt_nil); \
|
||||
} else { \
|
||||
assert(rbp_right_get(a_type, a_field, rbp_r_p) \
|
||||
== rbp_r_c); \
|
||||
rbp_right_set(a_type, a_field, rbp_r_p, \
|
||||
&(a_tree)->rbt_nil); \
|
||||
} \
|
||||
break; \
|
||||
} \
|
||||
rbp_r_u = rbp_left_get(a_type, a_field, rbp_r_t); \
|
||||
if (rbp_red_get(a_type, a_field, rbp_r_t) == false \
|
||||
&& rbp_red_get(a_type, a_field, rbp_r_u) == false) { \
|
||||
rbp_move_red_left(a_type, a_field, rbp_r_c, \
|
||||
rbp_r_t); \
|
||||
if (rbp_left_get(a_type, a_field, rbp_r_p) \
|
||||
== rbp_r_c) { \
|
||||
rbp_left_set(a_type, a_field, rbp_r_p, rbp_r_t);\
|
||||
} else { \
|
||||
rbp_right_set(a_type, a_field, rbp_r_p, \
|
||||
rbp_r_t); \
|
||||
} \
|
||||
rbp_r_c = rbp_r_t; \
|
||||
} else { \
|
||||
rbp_r_p = rbp_r_c; \
|
||||
rbp_r_c = rbp_left_get(a_type, a_field, rbp_r_c); \
|
||||
} \
|
||||
} else { \
|
||||
/* Check whether to delete this node (it has to be */\
|
||||
/* the correct node and a leaf node). */\
|
||||
if (rbp_r_cmp == 0) { \
|
||||
assert((a_node) == rbp_r_c); \
|
||||
if (rbp_right_get(a_type, a_field, rbp_r_c) \
|
||||
== &(a_tree)->rbt_nil) { \
|
||||
/* Delete leaf node. */\
|
||||
if (rbp_left_get(a_type, a_field, rbp_r_c) \
|
||||
!= &(a_tree)->rbt_nil) { \
|
||||
rbp_lean_right(a_type, a_field, rbp_r_c, \
|
||||
rbp_r_t); \
|
||||
rbp_right_set(a_type, a_field, rbp_r_t, \
|
||||
&(a_tree)->rbt_nil); \
|
||||
} else { \
|
||||
rbp_r_t = &(a_tree)->rbt_nil; \
|
||||
} \
|
||||
if (rbp_left_get(a_type, a_field, rbp_r_p) \
|
||||
== rbp_r_c) { \
|
||||
rbp_left_set(a_type, a_field, rbp_r_p, \
|
||||
rbp_r_t); \
|
||||
} else { \
|
||||
rbp_right_set(a_type, a_field, rbp_r_p, \
|
||||
rbp_r_t); \
|
||||
} \
|
||||
break; \
|
||||
} else { \
|
||||
/* This is the node we want to delete, but we */\
|
||||
/* will instead swap it with its successor */\
|
||||
/* and delete the successor. Record enough */\
|
||||
/* information to do the swap later. */\
|
||||
/* rbp_r_xp is a_node's parent. */\
|
||||
rbp_r_xp = rbp_r_p; \
|
||||
} \
|
||||
} \
|
||||
rbp_r_t = rbp_right_get(a_type, a_field, rbp_r_c); \
|
||||
rbp_r_u = rbp_left_get(a_type, a_field, rbp_r_t); \
|
||||
if (rbp_red_get(a_type, a_field, rbp_r_u) == false) { \
|
||||
rbp_move_red_right(a_type, a_field, rbp_r_c, \
|
||||
rbp_r_t); \
|
||||
if (rbp_left_get(a_type, a_field, rbp_r_p) \
|
||||
== rbp_r_c) { \
|
||||
rbp_left_set(a_type, a_field, rbp_r_p, rbp_r_t);\
|
||||
} else { \
|
||||
rbp_right_set(a_type, a_field, rbp_r_p, \
|
||||
rbp_r_t); \
|
||||
} \
|
||||
rbp_r_c = rbp_r_t; \
|
||||
} else { \
|
||||
rbp_r_p = rbp_r_c; \
|
||||
rbp_r_c = rbp_right_get(a_type, a_field, rbp_r_c); \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
/* Update root. */\
|
||||
(a_tree)->rbt_root = rbp_left_get(a_type, a_field, &rbp_r_s); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* The rb_wrap() macro provides a convenient way to wrap functions around the
|
||||
* cpp macros. The main benefits of wrapping are that 1) repeated macro
|
||||
* expansion can cause code bloat, especially for rb_{insert,remove)(), and
|
||||
* 2) type, linkage, comparison functions, etc. need not be specified at every
|
||||
* call point.
|
||||
*/
|
||||
|
||||
#define rb_wrap(a_attr, a_prefix, a_tree_type, a_type, a_field, a_cmp) \
|
||||
a_attr void \
|
||||
a_prefix##new(a_tree_type *tree) { \
|
||||
rb_new(a_type, a_field, tree); \
|
||||
} \
|
||||
a_attr a_type * \
|
||||
a_prefix##first(a_tree_type *tree) { \
|
||||
a_type *ret; \
|
||||
rb_first(a_type, a_field, tree, ret); \
|
||||
return (ret); \
|
||||
} \
|
||||
a_attr a_type * \
|
||||
a_prefix##last(a_tree_type *tree) { \
|
||||
a_type *ret; \
|
||||
rb_last(a_type, a_field, tree, ret); \
|
||||
return (ret); \
|
||||
} \
|
||||
a_attr a_type * \
|
||||
a_prefix##next(a_tree_type *tree, a_type *node) { \
|
||||
a_type *ret; \
|
||||
rb_next(a_type, a_field, a_cmp, tree, node, ret); \
|
||||
return (ret); \
|
||||
} \
|
||||
a_attr a_type * \
|
||||
a_prefix##prev(a_tree_type *tree, a_type *node) { \
|
||||
a_type *ret; \
|
||||
rb_prev(a_type, a_field, a_cmp, tree, node, ret); \
|
||||
return (ret); \
|
||||
} \
|
||||
a_attr a_type * \
|
||||
a_prefix##search(a_tree_type *tree, a_type *key) { \
|
||||
a_type *ret; \
|
||||
rb_search(a_type, a_field, a_cmp, tree, key, ret); \
|
||||
return (ret); \
|
||||
} \
|
||||
a_attr a_type * \
|
||||
a_prefix##nsearch(a_tree_type *tree, a_type *key) { \
|
||||
a_type *ret; \
|
||||
rb_nsearch(a_type, a_field, a_cmp, tree, key, ret); \
|
||||
return (ret); \
|
||||
} \
|
||||
a_attr a_type * \
|
||||
a_prefix##psearch(a_tree_type *tree, a_type *key) { \
|
||||
a_type *ret; \
|
||||
rb_psearch(a_type, a_field, a_cmp, tree, key, ret); \
|
||||
return (ret); \
|
||||
} \
|
||||
a_attr void \
|
||||
a_prefix##insert(a_tree_type *tree, a_type *node) { \
|
||||
rb_insert(a_type, a_field, a_cmp, tree, node); \
|
||||
} \
|
||||
a_attr void \
|
||||
a_prefix##remove(a_tree_type *tree, a_type *node) { \
|
||||
rb_remove(a_type, a_field, a_cmp, tree, node); \
|
||||
}
|
||||
|
||||
/*
|
||||
* The iterators simulate recursion via an array of pointers that store the
|
||||
* current path. This is critical to performance, since a series of calls to
|
||||
* rb_{next,prev}() would require time proportional to (n lg n), whereas this
|
||||
* implementation only requires time proportional to (n).
|
||||
*
|
||||
* Since the iterators cache a path down the tree, any tree modification may
|
||||
* cause the cached path to become invalid. In order to continue iteration,
|
||||
* use something like the following sequence:
|
||||
*
|
||||
* {
|
||||
* a_type *node, *tnode;
|
||||
*
|
||||
* rb_foreach_begin(a_type, a_field, a_tree, node) {
|
||||
* ...
|
||||
* rb_next(a_type, a_field, a_cmp, a_tree, node, tnode);
|
||||
* rb_remove(a_type, a_field, a_cmp, a_tree, node);
|
||||
* rb_foreach_next(a_type, a_field, a_cmp, a_tree, tnode);
|
||||
* ...
|
||||
* } rb_foreach_end(a_type, a_field, a_tree, node)
|
||||
* }
|
||||
*
|
||||
* Note that this idiom is not advised if every iteration modifies the tree,
|
||||
* since in that case there is no algorithmic complexity improvement over a
|
||||
* series of rb_{next,prev}() calls, thus making the setup overhead wasted
|
||||
* effort.
|
||||
*/
|
||||
|
||||
#ifdef RB_NO_C99_VARARRAYS
|
||||
/*
|
||||
* Avoid using variable-length arrays, at the cost of using more stack space.
|
||||
* Size the path arrays such that they are always large enough, even if a
|
||||
* tree consumes all of memory. Since each node must contain a minimum of
|
||||
* two pointers, there can never be more nodes than:
|
||||
*
|
||||
* 1 << ((SIZEOF_PTR<<3) - (SIZEOF_PTR_2POW+1))
|
||||
*
|
||||
* Since the depth of a tree is limited to 3*lg(#nodes), the maximum depth
|
||||
* is:
|
||||
*
|
||||
* (3 * ((SIZEOF_PTR<<3) - (SIZEOF_PTR_2POW+1)))
|
||||
*
|
||||
* This works out to a maximum depth of 87 and 180 for 32- and 64-bit
|
||||
* systems, respectively (approximatly 348 and 1440 bytes, respectively).
|
||||
*/
|
||||
# define rbp_compute_f_height(a_type, a_field, a_tree)
|
||||
# define rbp_f_height (3 * ((SIZEOF_PTR<<3) - (SIZEOF_PTR_2POW+1)))
|
||||
# define rbp_compute_fr_height(a_type, a_field, a_tree)
|
||||
# define rbp_fr_height (3 * ((SIZEOF_PTR<<3) - (SIZEOF_PTR_2POW+1)))
|
||||
#else
|
||||
# define rbp_compute_f_height(a_type, a_field, a_tree) \
|
||||
/* Compute the maximum possible tree depth (3X the black height). */\
|
||||
unsigned rbp_f_height; \
|
||||
rbp_black_height(a_type, a_field, a_tree, rbp_f_height); \
|
||||
rbp_f_height *= 3;
|
||||
# define rbp_compute_fr_height(a_type, a_field, a_tree) \
|
||||
/* Compute the maximum possible tree depth (3X the black height). */\
|
||||
unsigned rbp_fr_height; \
|
||||
rbp_black_height(a_type, a_field, a_tree, rbp_fr_height); \
|
||||
rbp_fr_height *= 3;
|
||||
#endif
|
||||
|
||||
#define rb_foreach_begin(a_type, a_field, a_tree, a_var) { \
|
||||
rbp_compute_f_height(a_type, a_field, a_tree) \
|
||||
{ \
|
||||
/* Initialize the path to contain the left spine. */\
|
||||
a_type *rbp_f_path[rbp_f_height]; \
|
||||
a_type *rbp_f_node; \
|
||||
bool rbp_f_synced = false; \
|
||||
unsigned rbp_f_depth = 0; \
|
||||
if ((a_tree)->rbt_root != &(a_tree)->rbt_nil) { \
|
||||
rbp_f_path[rbp_f_depth] = (a_tree)->rbt_root; \
|
||||
rbp_f_depth++; \
|
||||
while ((rbp_f_node = rbp_left_get(a_type, a_field, \
|
||||
rbp_f_path[rbp_f_depth-1])) != &(a_tree)->rbt_nil) { \
|
||||
rbp_f_path[rbp_f_depth] = rbp_f_node; \
|
||||
rbp_f_depth++; \
|
||||
} \
|
||||
} \
|
||||
/* While the path is non-empty, iterate. */\
|
||||
while (rbp_f_depth > 0) { \
|
||||
(a_var) = rbp_f_path[rbp_f_depth-1];
|
||||
|
||||
/* Only use if modifying the tree during iteration. */
|
||||
#define rb_foreach_next(a_type, a_field, a_cmp, a_tree, a_node) \
|
||||
/* Re-initialize the path to contain the path to a_node. */\
|
||||
rbp_f_depth = 0; \
|
||||
if (a_node != NULL) { \
|
||||
if ((a_tree)->rbt_root != &(a_tree)->rbt_nil) { \
|
||||
rbp_f_path[rbp_f_depth] = (a_tree)->rbt_root; \
|
||||
rbp_f_depth++; \
|
||||
rbp_f_node = rbp_f_path[0]; \
|
||||
while (true) { \
|
||||
int rbp_f_cmp = (a_cmp)((a_node), \
|
||||
rbp_f_path[rbp_f_depth-1]); \
|
||||
if (rbp_f_cmp < 0) { \
|
||||
rbp_f_node = rbp_left_get(a_type, a_field, \
|
||||
rbp_f_path[rbp_f_depth-1]); \
|
||||
} else if (rbp_f_cmp > 0) { \
|
||||
rbp_f_node = rbp_right_get(a_type, a_field, \
|
||||
rbp_f_path[rbp_f_depth-1]); \
|
||||
} else { \
|
||||
break; \
|
||||
} \
|
||||
assert(rbp_f_node != &(a_tree)->rbt_nil); \
|
||||
rbp_f_path[rbp_f_depth] = rbp_f_node; \
|
||||
rbp_f_depth++; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
rbp_f_synced = true;
|
||||
|
||||
#define rb_foreach_end(a_type, a_field, a_tree, a_var) \
|
||||
if (rbp_f_synced) { \
|
||||
rbp_f_synced = false; \
|
||||
continue; \
|
||||
} \
|
||||
/* Find the successor. */\
|
||||
if ((rbp_f_node = rbp_right_get(a_type, a_field, \
|
||||
rbp_f_path[rbp_f_depth-1])) != &(a_tree)->rbt_nil) { \
|
||||
/* The successor is the left-most node in the right */\
|
||||
/* subtree. */\
|
||||
rbp_f_path[rbp_f_depth] = rbp_f_node; \
|
||||
rbp_f_depth++; \
|
||||
while ((rbp_f_node = rbp_left_get(a_type, a_field, \
|
||||
rbp_f_path[rbp_f_depth-1])) != &(a_tree)->rbt_nil) { \
|
||||
rbp_f_path[rbp_f_depth] = rbp_f_node; \
|
||||
rbp_f_depth++; \
|
||||
} \
|
||||
} else { \
|
||||
/* The successor is above the current node. Unwind */\
|
||||
/* until a left-leaning edge is removed from the */\
|
||||
/* path, or the path is empty. */\
|
||||
for (rbp_f_depth--; rbp_f_depth > 0; rbp_f_depth--) { \
|
||||
if (rbp_left_get(a_type, a_field, \
|
||||
rbp_f_path[rbp_f_depth-1]) \
|
||||
== rbp_f_path[rbp_f_depth]) { \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#define rb_foreach_reverse_begin(a_type, a_field, a_tree, a_var) { \
|
||||
rbp_compute_fr_height(a_type, a_field, a_tree) \
|
||||
{ \
|
||||
/* Initialize the path to contain the right spine. */\
|
||||
a_type *rbp_fr_path[rbp_fr_height]; \
|
||||
a_type *rbp_fr_node; \
|
||||
bool rbp_fr_synced = false; \
|
||||
unsigned rbp_fr_depth = 0; \
|
||||
if ((a_tree)->rbt_root != &(a_tree)->rbt_nil) { \
|
||||
rbp_fr_path[rbp_fr_depth] = (a_tree)->rbt_root; \
|
||||
rbp_fr_depth++; \
|
||||
while ((rbp_fr_node = rbp_right_get(a_type, a_field, \
|
||||
rbp_fr_path[rbp_fr_depth-1])) != &(a_tree)->rbt_nil) { \
|
||||
rbp_fr_path[rbp_fr_depth] = rbp_fr_node; \
|
||||
rbp_fr_depth++; \
|
||||
} \
|
||||
} \
|
||||
/* While the path is non-empty, iterate. */\
|
||||
while (rbp_fr_depth > 0) { \
|
||||
(a_var) = rbp_fr_path[rbp_fr_depth-1];
|
||||
|
||||
/* Only use if modifying the tree during iteration. */
|
||||
#define rb_foreach_reverse_prev(a_type, a_field, a_cmp, a_tree, a_node) \
|
||||
/* Re-initialize the path to contain the path to a_node. */\
|
||||
rbp_fr_depth = 0; \
|
||||
if (a_node != NULL) { \
|
||||
if ((a_tree)->rbt_root != &(a_tree)->rbt_nil) { \
|
||||
rbp_fr_path[rbp_fr_depth] = (a_tree)->rbt_root; \
|
||||
rbp_fr_depth++; \
|
||||
rbp_fr_node = rbp_fr_path[0]; \
|
||||
while (true) { \
|
||||
int rbp_fr_cmp = (a_cmp)((a_node), \
|
||||
rbp_fr_path[rbp_fr_depth-1]); \
|
||||
if (rbp_fr_cmp < 0) { \
|
||||
rbp_fr_node = rbp_left_get(a_type, a_field, \
|
||||
rbp_fr_path[rbp_fr_depth-1]); \
|
||||
} else if (rbp_fr_cmp > 0) { \
|
||||
rbp_fr_node = rbp_right_get(a_type, a_field,\
|
||||
rbp_fr_path[rbp_fr_depth-1]); \
|
||||
} else { \
|
||||
break; \
|
||||
} \
|
||||
assert(rbp_fr_node != &(a_tree)->rbt_nil); \
|
||||
rbp_fr_path[rbp_fr_depth] = rbp_fr_node; \
|
||||
rbp_fr_depth++; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
rbp_fr_synced = true;
|
||||
|
||||
#define rb_foreach_reverse_end(a_type, a_field, a_tree, a_var) \
|
||||
if (rbp_fr_synced) { \
|
||||
rbp_fr_synced = false; \
|
||||
continue; \
|
||||
} \
|
||||
if (rbp_fr_depth == 0) { \
|
||||
/* rb_foreach_reverse_sync() was called with a NULL */\
|
||||
/* a_node. */\
|
||||
break; \
|
||||
} \
|
||||
/* Find the predecessor. */\
|
||||
if ((rbp_fr_node = rbp_left_get(a_type, a_field, \
|
||||
rbp_fr_path[rbp_fr_depth-1])) != &(a_tree)->rbt_nil) { \
|
||||
/* The predecessor is the right-most node in the left */\
|
||||
/* subtree. */\
|
||||
rbp_fr_path[rbp_fr_depth] = rbp_fr_node; \
|
||||
rbp_fr_depth++; \
|
||||
while ((rbp_fr_node = rbp_right_get(a_type, a_field, \
|
||||
rbp_fr_path[rbp_fr_depth-1])) != &(a_tree)->rbt_nil) {\
|
||||
rbp_fr_path[rbp_fr_depth] = rbp_fr_node; \
|
||||
rbp_fr_depth++; \
|
||||
} \
|
||||
} else { \
|
||||
/* The predecessor is above the current node. Unwind */\
|
||||
/* until a right-leaning edge is removed from the */\
|
||||
/* path, or the path is empty. */\
|
||||
for (rbp_fr_depth--; rbp_fr_depth > 0; rbp_fr_depth--) {\
|
||||
if (rbp_right_get(a_type, a_field, \
|
||||
rbp_fr_path[rbp_fr_depth-1]) \
|
||||
== rbp_fr_path[rbp_fr_depth]) { \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
}
|
||||
|
||||
#endif /* RB_H_ */
|
0
apilibs/kexbasen/kernel32/unikernel32.c
Normal file → Executable file
0
apilibs/kexbasen/kernel32/unikernel32.c
Normal file → Executable file
0
apilibs/kexbasen/kexbasen.def
Normal file → Executable file
0
apilibs/kexbasen/kexbasen.def
Normal file → Executable file
141
apilibs/kexbasen/kexbasen.dsp
Normal file → Executable file
141
apilibs/kexbasen/kexbasen.dsp
Normal file → Executable file
@ -53,7 +53,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shlwapi.lib shell32.lib rpcrt4.lib usp10.lib ../../common/KernelEx.lib ../../kexcrt/kexcrt.lib libc.lib delayimp.lib /nologo /dll /map /machine:I386 /nodefaultlib /OPT:NOWIN98 /DELAYLOAD:shell32.dll /DELAYLOAD:rpcrt4.dll /DELAYLOAD:usp10.dll /DELAYLOAD:comdlg32.dll /DELAYLOAD:winspool.drv /DELAYLOAD:shlwapi.dll
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shlwapi.lib shell32.lib rpcrt4.lib usp10.lib ../../common/KernelEx.lib ../../kexcrt/kexcrt.lib libc.lib delayimp.lib /nologo /dll /map /machine:I386 /nodefaultlib /OPT:NOWIN98 /DELAYLOAD:shell32.dll /DELAYLOAD:rpcrt4.dll /DELAYLOAD:usp10.dll /DELAYLOAD:comdlg32.dll /DELAYLOAD:winspool.drv
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ELSEIF "$(CFG)" == "KernelEx Base NonShared - Win32 Debug"
|
||||
@ -80,7 +80,7 @@ BSC32=bscmake.exe
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shlwapi.lib shell32.lib rpcrt4.lib usp10.lib ../../common/KernelEx.lib ../../kexcrt/kexcrt.lib libc.lib delayimp.lib /nologo /dll /map /debug /machine:I386 /nodefaultlib /pdbtype:sept /OPT:NOWIN98 /DELAYLOAD:shell32.dll /DELAYLOAD:rpcrt4.dll /DELAYLOAD:usp10.dll /DELAYLOAD:comdlg32.dll /DELAYLOAD:winspool.drv /DELAYLOAD:shlwapi.dll
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shlwapi.lib shell32.lib rpcrt4.lib usp10.lib ../../common/KernelEx.lib ../../kexcrt/kexcrt.lib libc.lib delayimp.lib /nologo /dll /map /debug /machine:I386 /nodefaultlib /OPT:NOWIN98 /DELAYLOAD:shell32.dll /DELAYLOAD:rpcrt4.dll /DELAYLOAD:usp10.dll /DELAYLOAD:comdlg32.dll /DELAYLOAD:winspool.drv
|
||||
# SUBTRACT LINK32 /pdb:none
|
||||
|
||||
!ENDIF
|
||||
@ -105,6 +105,22 @@ SOURCE=.\kernel32\_kernel32_apilist.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\kernel32\allocator.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\kernel32\DelayLoadFailureHook.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\kernel32\ThreadPool.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\kernel32\TlsExt.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\kernel32\unikernel32.c
|
||||
# End Source File
|
||||
# End Group
|
||||
@ -193,11 +209,7 @@ SOURCE=.\shell32\_shell32_apilist.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\shell32\auxshlguid.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\shell32\pidl.h
|
||||
SOURCE=.\shell32\folderfix.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@ -209,6 +221,10 @@ SOURCE=.\shell32\SHGetFolderPath.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\shell32\SHGetSpecialFolder_fix.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\shell32\unishell32.c
|
||||
# End Source File
|
||||
# End Group
|
||||
@ -241,23 +257,31 @@ SOURCE=.\winspool\_winspool_apilist.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\winspool\_winspool_stubs.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\winspool\DefaultPrinter.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\winspool\uniwinspool.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "shlwapi"
|
||||
# Begin Group "shfolder"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\shlwapi\_shlwapi_apilist.c
|
||||
SOURCE=.\shfolder\_shfolder_apilist.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\shlwapi\_shlwapi_apilist.h
|
||||
SOURCE=.\shfolder\_shfolder_apilist.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\shlwapi\string.c
|
||||
SOURCE=.\shfolder\shfolder.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
@ -266,7 +290,85 @@ SOURCE=.\common.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\dirlist
|
||||
|
||||
!IF "$(CFG)" == "KernelEx Base NonShared - Win32 Release"
|
||||
|
||||
# Begin Custom Build
|
||||
WkspDir=.
|
||||
ProjDir=.
|
||||
InputPath=.\dirlist
|
||||
|
||||
"&" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
if not exist $(WkspDir)\util\prep\Release\prep.exe goto error
|
||||
$(WkspDir)\util\prep\Release\prep.exe "$(ProjDir)"
|
||||
goto quit
|
||||
:error
|
||||
echo Error - compile PREP (Release) project first
|
||||
echo 1 | choice /C:1 /N >NUL
|
||||
:quit
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "KernelEx Base NonShared - Win32 Debug"
|
||||
|
||||
# Begin Custom Build
|
||||
WkspDir=.
|
||||
ProjDir=.
|
||||
InputPath=.\dirlist
|
||||
|
||||
"&" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
if not exist $(WkspDir)\util\prep\Release\prep.exe goto error
|
||||
$(WkspDir)\util\prep\Release\prep.exe "$(ProjDir)"
|
||||
goto quit
|
||||
:error
|
||||
echo Error - compile PREP (Release) project first
|
||||
echo 1 | choice /C:1 /N >NUL
|
||||
:quit
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\kexbasen.def
|
||||
|
||||
!IF "$(CFG)" == "KernelEx Base NonShared - Win32 Release"
|
||||
|
||||
# Begin Custom Build
|
||||
OutDir=.\Release
|
||||
WkspDir=.
|
||||
InputPath=.\kexbasen.def
|
||||
|
||||
"$(OutDir)\k32ord.lib" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
cl /nologo /c /TC /DK32ORD_IMPLIB /Fo$(OutDir)\k32ord.obj "$(WkspDir)\common\k32ord.h"
|
||||
link /DLL /NOENTRY /NOLOGO /IGNORE:4070 /MACHINE:IX86 /DEF:"$(WkspDir)\common\k32ord.def" /OUT:$(OutDir)\k32ord.dll /IMPLIB:$(OutDir)\k32ord.lib $(OutDir)\k32ord.obj
|
||||
del $(OutDir)\k32ord.exp
|
||||
del $(OutDir)\k32ord.obj
|
||||
del $(OutDir)\k32ord.dll
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "KernelEx Base NonShared - Win32 Debug"
|
||||
|
||||
# Begin Custom Build
|
||||
OutDir=.\Debug
|
||||
WkspDir=.
|
||||
InputPath=.\kexbasen.def
|
||||
|
||||
"$(OutDir)\k32ord.lib" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
cl /nologo /c /TC /DK32ORD_IMPLIB /Fo$(OutDir)\k32ord.obj "$(WkspDir)\common\k32ord.h"
|
||||
link /DLL /NOENTRY /NOLOGO /IGNORE:4070 /MACHINE:IX86 /DEF:"$(WkspDir)\common\k32ord.def" /OUT:$(OutDir)\k32ord.dll /IMPLIB:$(OutDir)\k32ord.lib $(OutDir)\k32ord.obj
|
||||
del $(OutDir)\k32ord.exp
|
||||
del $(OutDir)\k32ord.obj
|
||||
del $(OutDir)\k32ord.dll
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
@ -274,6 +376,10 @@ SOURCE=.\main.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\shlord.c
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\unifwd.c
|
||||
# End Source File
|
||||
# End Group
|
||||
@ -286,6 +392,19 @@ SOURCE=.\common.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\common\k32ord.def
|
||||
# PROP Exclude_From_Build 1
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\..\common\k32ord.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\shlord.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\unifwd.h
|
||||
# End Source File
|
||||
# End Group
|
||||
|
2
apilibs/kexbasen/kexbasen.rc
Normal file → Executable file
2
apilibs/kexbasen/kexbasen.rc
Normal file → Executable file
@ -74,7 +74,7 @@ BEGIN
|
||||
VALUE "FileDescription", "KernelEx Base Non-shared Api Library\0"
|
||||
VALUE "FileVersion", _RCVERSION_ "\0"
|
||||
VALUE "InternalName", "kexbasen\0"
|
||||
VALUE "LegalCopyright", "Copyright <20> 2009, Xeno86\0"
|
||||
VALUE "LegalCopyright", "Copyright <20> 2009-2010, Xeno86\0"
|
||||
VALUE "LegalTrademarks", "\0"
|
||||
VALUE "OriginalFilename", "kexbasen.dll\0"
|
||||
VALUE "PrivateBuild", "\0"
|
||||
|
25
apilibs/kexbasen/main.c
Normal file → Executable file
25
apilibs/kexbasen/main.c
Normal file → Executable file
@ -30,7 +30,7 @@
|
||||
#include "shell32/_shell32_apilist.h"
|
||||
#include "rpcrt4/_rpcrt4_apilist.h"
|
||||
#include "winspool/_winspool_apilist.h"
|
||||
#include "shlwapi/_shlwapi_apilist.h"
|
||||
#include "shfolder/_shfolder_apilist.h"
|
||||
//#include "/__apilist.h"
|
||||
|
||||
static apilib_api_table api_table[10];
|
||||
@ -45,7 +45,7 @@ static void fill_apitable()
|
||||
api_table[5] = apitable_shell32;
|
||||
api_table[6] = apitable_rpcrt4;
|
||||
api_table[7] = apitable_winspool;
|
||||
api_table[8] = apitable_shlwapi;
|
||||
api_table[8] = apitable_shfolder;
|
||||
//last entry is null terminator
|
||||
}
|
||||
|
||||
@ -57,9 +57,19 @@ const apilib_api_table* get_api_table()
|
||||
return api_table;
|
||||
}
|
||||
|
||||
BOOL init()
|
||||
static BOOL init()
|
||||
{
|
||||
return common_init() && init_kernel32() && init_gdi32() && init_user32() && init_advapi32() && init_comdlg32() && init_shell32() && init_rpcrt4() && init_winspool() && init_shlwapi();
|
||||
return common_init() && init_kernel32() && init_gdi32() && init_user32() && init_advapi32() && init_comdlg32() && init_shell32() && init_rpcrt4() && init_winspool() && init_shfolder();
|
||||
}
|
||||
|
||||
static void uninit()
|
||||
{
|
||||
uninit_kernel32();
|
||||
}
|
||||
|
||||
static void detach()
|
||||
{
|
||||
detach_kernel32();
|
||||
}
|
||||
|
||||
BOOL APIENTRY DllMain(HINSTANCE instance, DWORD reason, BOOL load_static)
|
||||
@ -67,13 +77,14 @@ BOOL APIENTRY DllMain(HINSTANCE instance, DWORD reason, BOOL load_static)
|
||||
switch (reason)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
// kexDebugPrint("KernelEx Base Non-shared library reporting in action!\n");
|
||||
DisableThreadLibraryCalls(instance);
|
||||
if (!init())
|
||||
return FALSE;
|
||||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
// kexDebugPrint("KernelEx Base Non-shared library signing off!\n");
|
||||
uninit();
|
||||
break;
|
||||
case DLL_THREAD_DETACH:
|
||||
detach();
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
|
0
apilibs/kexbasen/resource.h
Normal file → Executable file
0
apilibs/kexbasen/resource.h
Normal file → Executable file
0
apilibs/kexbasen/rpcrt4/_rpcrt4_apilist.c
Normal file → Executable file
0
apilibs/kexbasen/rpcrt4/_rpcrt4_apilist.c
Normal file → Executable file
0
apilibs/kexbasen/rpcrt4/_rpcrt4_apilist.h
Normal file → Executable file
0
apilibs/kexbasen/rpcrt4/_rpcrt4_apilist.h
Normal file → Executable file
0
apilibs/kexbasen/rpcrt4/unirpcrt4.c
Normal file → Executable file
0
apilibs/kexbasen/rpcrt4/unirpcrt4.c
Normal file → Executable file
305
apilibs/kexbasen/shell32/SHGetFolderLocation.c
Normal file → Executable file
305
apilibs/kexbasen/shell32/SHGetFolderLocation.c
Normal file → Executable file
@ -1,286 +1,54 @@
|
||||
/*
|
||||
* Path Functions
|
||||
* KernelEx
|
||||
* Copyright (C) 2009, Xeno86, Tihiy
|
||||
*
|
||||
* Copyright 1998, 1999, 2000 Juergen Schmied
|
||||
* Copyright 2004 Juan Lang
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
* 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.
|
||||
* KernelEx is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* KernelEx 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.
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU 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
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable:4002)
|
||||
#define TRACE() ((void)0)
|
||||
#define TRACE_() ((void)0)
|
||||
#define WARN() ((void)0)
|
||||
#else
|
||||
#define TRACE(...) do {} while(0)
|
||||
#define TRACE_(x) TRACE
|
||||
#define WARN(...) do {} while(0)
|
||||
#endif
|
||||
|
||||
#define _WIN32_IE 0x0500
|
||||
|
||||
#include <windows.h>
|
||||
#include <shlguid.h>
|
||||
#include "auxshlguid.h"
|
||||
#include "pidl.h"
|
||||
#include <shlwapi.h>
|
||||
#include <shlobj.h>
|
||||
#include "common.h"
|
||||
#include "_shell32_apilist.h"
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* internal functions
|
||||
*
|
||||
* ### 1. section creating pidls ###
|
||||
*
|
||||
*************************************************************************
|
||||
*/
|
||||
LPITEMIDLIST _ILAlloc(PIDLTYPE type, unsigned int size)
|
||||
{
|
||||
LPITEMIDLIST pidlOut = NULL;
|
||||
typedef HRESULT (WINAPI *SHGetFolderLocation_t)(HWND, int, HANDLE, DWORD, LPVOID*);
|
||||
|
||||
pidlOut = (LPITEMIDLIST) SHAlloc(size + 5);
|
||||
if(pidlOut)
|
||||
{
|
||||
LPPIDLDATA pData;
|
||||
LPITEMIDLIST pidlNext;
|
||||
|
||||
ZeroMemory(pidlOut, size + 5);
|
||||
pidlOut->mkid.cb = size + 3;
|
||||
|
||||
pData = _ILGetDataPointer(pidlOut);
|
||||
if (pData)
|
||||
pData->type = type;
|
||||
|
||||
pidlNext = ILGetNext(pidlOut);
|
||||
if (pidlNext)
|
||||
pidlNext->mkid.cb = 0x00;
|
||||
TRACE("-- (pidl=%p, size=%u)\n", pidlOut, size);
|
||||
}
|
||||
|
||||
return pidlOut;
|
||||
}
|
||||
|
||||
LPITEMIDLIST _ILCreateDesktop()
|
||||
{
|
||||
LPITEMIDLIST ret;
|
||||
|
||||
TRACE("()\n");
|
||||
ret = (LPITEMIDLIST) SHAlloc(2);
|
||||
if (ret)
|
||||
ret->mkid.cb = 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
LPITEMIDLIST _ILCreateMyComputer()
|
||||
{
|
||||
TRACE("()\n");
|
||||
return _ILCreateGuid(PT_GUID, &CLSID_MyComputer);
|
||||
}
|
||||
|
||||
LPITEMIDLIST _ILCreateMyDocuments()
|
||||
{
|
||||
TRACE("()\n");
|
||||
return _ILCreateGuid(PT_GUID, &CLSID_MyDocuments);
|
||||
}
|
||||
|
||||
LPITEMIDLIST _ILCreateIExplore()
|
||||
{
|
||||
TRACE("()\n");
|
||||
return _ILCreateGuid(PT_GUID, &CLSID_Internet);
|
||||
}
|
||||
|
||||
LPITEMIDLIST _ILCreateControlPanel()
|
||||
{
|
||||
LPITEMIDLIST parent = _ILCreateGuid(PT_GUID, &CLSID_MyComputer), ret = NULL;
|
||||
|
||||
TRACE("()\n");
|
||||
if (parent)
|
||||
{
|
||||
LPITEMIDLIST cpl = _ILCreateGuid(PT_SHELLEXT, &CLSID_ControlPanel);
|
||||
|
||||
if (cpl)
|
||||
{
|
||||
ret = ILCombine(parent, cpl);
|
||||
SHFree(cpl);
|
||||
}
|
||||
SHFree(parent);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
LPITEMIDLIST _ILCreatePrinters()
|
||||
{
|
||||
LPITEMIDLIST parent = _ILCreateGuid(PT_GUID, &CLSID_MyComputer), ret = NULL;
|
||||
|
||||
TRACE("()\n");
|
||||
if (parent)
|
||||
{
|
||||
LPITEMIDLIST printers = _ILCreateGuid(PT_YAGUID, &CLSID_Printers);
|
||||
|
||||
if (printers)
|
||||
{
|
||||
ret = ILCombine(parent, printers);
|
||||
SHFree(printers);
|
||||
}
|
||||
SHFree(parent);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
LPITEMIDLIST _ILCreateNetwork()
|
||||
{
|
||||
TRACE("()\n");
|
||||
return _ILCreateGuid(PT_GUID, &CLSID_NetworkPlaces);
|
||||
}
|
||||
|
||||
LPITEMIDLIST _ILCreateBitBucket()
|
||||
{
|
||||
TRACE("()\n");
|
||||
return _ILCreateGuid(PT_GUID, &CLSID_RecycleBin);
|
||||
}
|
||||
|
||||
LPITEMIDLIST _ILCreateGuid(PIDLTYPE type, const IID *guid)
|
||||
{
|
||||
LPITEMIDLIST pidlOut;
|
||||
|
||||
if (type == PT_SHELLEXT || type == PT_GUID || type == PT_YAGUID)
|
||||
{
|
||||
pidlOut = _ILAlloc(type, sizeof(GUIDStruct));
|
||||
if (pidlOut)
|
||||
{
|
||||
LPPIDLDATA pData = _ILGetDataPointer(pidlOut);
|
||||
|
||||
memcpy(&(pData->u.guid.guid), guid, sizeof(GUID));
|
||||
TRACE("-- create GUID-pidl %s\n",
|
||||
debugstr_guid(&(pData->u.guid.guid)));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
WARN("%d: invalid type for GUID\n", type);
|
||||
pidlOut = NULL;
|
||||
}
|
||||
return pidlOut;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
*
|
||||
* ### 4. getting pointers to parts of pidls ###
|
||||
*
|
||||
**************************************************************************
|
||||
* _ILGetDataPointer()
|
||||
*/
|
||||
LPPIDLDATA _ILGetDataPointer(LPCITEMIDLIST pidl)
|
||||
{
|
||||
if(pidl && pidl->mkid.cb != 0x00)
|
||||
return (LPPIDLDATA) &(pidl->mkid.abID);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* SHGetFolderLocation [SHELL32.@]
|
||||
*
|
||||
* Gets the folder locations from the registry and creates a pidl.
|
||||
*
|
||||
* PARAMS
|
||||
* hwndOwner [I]
|
||||
* nFolder [I] CSIDL_xxxxx
|
||||
* hToken [I] token representing user, or NULL for current user, or -1 for
|
||||
* default user
|
||||
* dwReserved [I] must be zero
|
||||
* ppidl [O] PIDL of a special folder
|
||||
*
|
||||
* RETURNS
|
||||
* Success: S_OK
|
||||
* Failure: Standard OLE-defined error result, S_FALSE or E_INVALIDARG
|
||||
*
|
||||
* NOTES
|
||||
* Creates missing reg keys and directories.
|
||||
* Mostly forwards to SHGetFolderPathW, but a few values of nFolder return
|
||||
* virtual folders that are handled here.
|
||||
*/
|
||||
/* MAKE_EXPORT SHGetFolderLocation_new=SHGetFolderLocation */
|
||||
HRESULT WINAPI SHGetFolderLocation_new(
|
||||
HRESULT WINAPI SHGetFolderLocation_impl(
|
||||
HWND hwndOwner,
|
||||
int nFolder,
|
||||
HANDLE hToken,
|
||||
DWORD dwReserved,
|
||||
LPVOID *_ppidl)
|
||||
LPVOID *ppidl
|
||||
)
|
||||
{
|
||||
LPITEMIDLIST *ppidl = (LPITEMIDLIST*) _ppidl;
|
||||
HRESULT hr = E_INVALIDARG;
|
||||
|
||||
TRACE("%p 0x%08x %p 0x%08lx %p\n",
|
||||
hwndOwner, nFolder, hToken, dwReserved, ppidl);
|
||||
|
||||
if (!ppidl)
|
||||
return E_INVALIDARG;
|
||||
if (dwReserved)
|
||||
return E_INVALIDARG;
|
||||
|
||||
/* The virtual folders' locations are not user-dependent */
|
||||
*ppidl = NULL;
|
||||
switch (nFolder)
|
||||
{
|
||||
case CSIDL_DESKTOP:
|
||||
*ppidl = _ILCreateDesktop();
|
||||
break;
|
||||
|
||||
case CSIDL_PERSONAL:
|
||||
*ppidl = _ILCreateMyDocuments();
|
||||
break;
|
||||
|
||||
case CSIDL_INTERNET:
|
||||
*ppidl = _ILCreateIExplore();
|
||||
break;
|
||||
|
||||
case CSIDL_CONTROLS:
|
||||
*ppidl = _ILCreateControlPanel();
|
||||
break;
|
||||
|
||||
case CSIDL_PRINTERS:
|
||||
*ppidl = _ILCreatePrinters();
|
||||
break;
|
||||
|
||||
case CSIDL_BITBUCKET:
|
||||
*ppidl = _ILCreateBitBucket();
|
||||
break;
|
||||
|
||||
case CSIDL_DRIVES:
|
||||
*ppidl = _ILCreateMyComputer();
|
||||
break;
|
||||
|
||||
case CSIDL_NETWORK:
|
||||
*ppidl = _ILCreateNetwork();
|
||||
break;
|
||||
|
||||
default:
|
||||
HRESULT hr = SHGetSpecialFolderLocation_fix(hwndOwner, nFolder, ppidl);
|
||||
if (!SUCCEEDED(hr))
|
||||
{
|
||||
char szPath[MAX_PATH];
|
||||
|
||||
hr = SHGetFolderPathA_new(hwndOwner, nFolder, hToken,
|
||||
SHGFP_TYPE_CURRENT, szPath);
|
||||
hr = SHGetFolderPathA_new(hwndOwner, nFolder, hToken, SHGFP_TYPE_CURRENT, szPath);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
DWORD attributes=0;
|
||||
|
||||
TRACE("Value=%s\n", debugstr_w(szPath));
|
||||
hr = SHILCreateFromPath((LPWSTR)szPath, ppidl, &attributes);
|
||||
DWORD attributes = 0;
|
||||
hr = SHILCreateFromPath((LPWSTR)szPath, (LPITEMIDLIST*)ppidl, &attributes);
|
||||
}
|
||||
else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
|
||||
{
|
||||
@ -290,11 +58,32 @@ HRESULT WINAPI SHGetFolderLocation_new(
|
||||
hr = E_FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(*ppidl)
|
||||
if (*ppidl)
|
||||
hr = NOERROR;
|
||||
|
||||
TRACE("-- (new pidl %p)\n",*ppidl);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static SHGetFolderLocation_t dld()
|
||||
{
|
||||
HMODULE h = GetModuleHandle("SHELL32");
|
||||
SHGetFolderLocation_t pfn = (SHGetFolderLocation_t)
|
||||
GetProcAddress(h, "SHGetFolderLocation");
|
||||
if (!pfn)
|
||||
pfn = SHGetFolderLocation_impl;
|
||||
return pfn;
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT SHGetFolderLocation_new=SHGetFolderLocation */
|
||||
HRESULT WINAPI SHGetFolderLocation_new(
|
||||
HWND hwndOwner,
|
||||
int nFolder,
|
||||
HANDLE hToken,
|
||||
DWORD dwReserved,
|
||||
LPVOID *ppidl
|
||||
)
|
||||
{
|
||||
static SHGetFolderLocation_t SHGetFolderLocation_pfn;
|
||||
if (!SHGetFolderLocation_pfn)
|
||||
SHGetFolderLocation_pfn = dld();
|
||||
return SHGetFolderLocation_pfn(hwndOwner, nFolder, hToken, dwReserved, ppidl);
|
||||
}
|
||||
|
19
apilibs/kexbasen/shell32/SHGetFolderPath.c
Normal file → Executable file
19
apilibs/kexbasen/shell32/SHGetFolderPath.c
Normal file → Executable file
@ -20,14 +20,13 @@
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <shlobj.h>
|
||||
#include "kexcoresdk.h"
|
||||
#include "folderfix.h"
|
||||
|
||||
typedef HRESULT (WINAPI *SHGetFolderPathA_t)(HWND, int, HANDLE, DWORD, LPSTR);
|
||||
typedef HRESULT (WINAPI *SHGetFolderPathW_t)(HWND, int, HANDLE, DWORD, LPWSTR);
|
||||
|
||||
static SHGetFolderPathA_t SHGetFolderPathA_pfn = (SHGetFolderPathA_t)-1;
|
||||
static SHGetFolderPathW_t SHGetFolderPathW_pfn = (SHGetFolderPathW_t)-1;
|
||||
|
||||
static PROC LoadShfolderProc(const char* proc)
|
||||
{
|
||||
static const char ShfolderFn[] = "SHFOLDER.DLL";
|
||||
@ -39,20 +38,14 @@ static PROC LoadShfolderProc(const char* proc)
|
||||
|
||||
//first try with shell32
|
||||
if (!hShell32)
|
||||
{
|
||||
hShell32 = GetModuleHandle(Shell32Fn);
|
||||
if (!hShell32) hShell32 = LoadLibrary(Shell32Fn);
|
||||
}
|
||||
hShell32 = LoadLibrary(Shell32Fn);
|
||||
if (hShell32) ret = kexGetProcAddress(hShell32, proc);
|
||||
|
||||
//fallback to shfolder
|
||||
if (!ret)
|
||||
{
|
||||
if (!hShfolder)
|
||||
{
|
||||
hShfolder = GetModuleHandle(ShfolderFn);
|
||||
if (!hShfolder) hShfolder = LoadLibrary(ShfolderFn);
|
||||
}
|
||||
hShfolder = LoadLibrary(ShfolderFn);
|
||||
if (hShfolder) ret = kexGetProcAddress(hShfolder, proc);
|
||||
}
|
||||
SetLastError(lasterr);
|
||||
@ -62,19 +55,23 @@ static PROC LoadShfolderProc(const char* proc)
|
||||
/* MAKE_EXPORT SHGetFolderPathA_new=SHGetFolderPathA */
|
||||
HRESULT WINAPI SHGetFolderPathA_new(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPSTR pszPath)
|
||||
{
|
||||
static SHGetFolderPathA_t SHGetFolderPathA_pfn = (SHGetFolderPathA_t)-1;
|
||||
if (SHGetFolderPathA_pfn == (void*)-1)
|
||||
SHGetFolderPathA_pfn = (SHGetFolderPathA_t) LoadShfolderProc("SHGetFolderPathA");
|
||||
if (SHGetFolderPathA_pfn == NULL)
|
||||
return E_NOTIMPL;
|
||||
nFolder = folder_fix(nFolder);
|
||||
return SHGetFolderPathA_pfn(hwndOwner, nFolder, hToken, dwFlags, pszPath);
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT SHGetFolderPathW_new=SHGetFolderPathW */
|
||||
HRESULT WINAPI SHGetFolderPathW_new(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath)
|
||||
{
|
||||
static SHGetFolderPathW_t SHGetFolderPathW_pfn = (SHGetFolderPathW_t)-1;
|
||||
if (SHGetFolderPathW_pfn == (void*)-1)
|
||||
SHGetFolderPathW_pfn = (SHGetFolderPathW_t) LoadShfolderProc("SHGetFolderPathW");
|
||||
if (SHGetFolderPathW_pfn == NULL)
|
||||
return E_NOTIMPL;
|
||||
nFolder = folder_fix(nFolder);
|
||||
return SHGetFolderPathW_pfn(hwndOwner, nFolder, hToken, dwFlags, pszPath);
|
||||
}
|
||||
|
47
apilibs/kexbasen/shell32/SHGetSpecialFolder_fix.c
Executable file
47
apilibs/kexbasen/shell32/SHGetSpecialFolder_fix.c
Executable file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* KernelEx
|
||||
* Copyright (C) 2009, Xeno86
|
||||
*
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
* KernelEx is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* KernelEx is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <shlobj.h>
|
||||
#include "folderfix.h"
|
||||
|
||||
/* MAKE_EXPORT SHGetSpecialFolderLocation_fix=SHGetSpecialFolderLocation */
|
||||
HRESULT WINAPI SHGetSpecialFolderLocation_fix(HWND hwndOwner, int nFolder, LPVOID *_ppidl)
|
||||
{
|
||||
LPITEMIDLIST *ppidl = (LPITEMIDLIST*) _ppidl;
|
||||
// explorer shouldn't receive this because of start menu bug which displays entries twice
|
||||
if (GetModuleHandle("EXPLORER.EXE") == NULL)
|
||||
nFolder = folder_fix(nFolder);
|
||||
return SHGetSpecialFolderLocation(hwndOwner, nFolder, ppidl);
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT SHGetSpecialFolderPathA_fix=SHGetSpecialFolderPathA */
|
||||
BOOL WINAPI SHGetSpecialFolderPathA_fix(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate)
|
||||
{
|
||||
nFolder = folder_fix(nFolder);
|
||||
return SHGetSpecialFolderPathA(hwndOwner, lpszPath, nFolder, fCreate);
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT SHGetSpecialFolderPathW_fix=SHGetSpecialFolderPathW */
|
||||
BOOL WINAPI SHGetSpecialFolderPathW_fix(HWND hwndOwner, LPWSTR lpszPath, int nFolder, BOOL fCreate)
|
||||
{
|
||||
nFolder = folder_fix(nFolder);
|
||||
return SHGetSpecialFolderPathW(hwndOwner, lpszPath, nFolder, fCreate);
|
||||
}
|
3
apilibs/kexbasen/shell32/_shell32_apilist.c
Normal file → Executable file
3
apilibs/kexbasen/shell32/_shell32_apilist.c
Normal file → Executable file
@ -42,6 +42,9 @@ static const apilib_named_api shell32_named_apis[] =
|
||||
DECL_API("SHGetFolderPathA", SHGetFolderPathA_new),
|
||||
DECL_API("SHGetFolderPathW", SHGetFolderPathW_new),
|
||||
DECL_API("SHGetNewLinkInfoW", SHGetNewLinkInfoW_fwd),
|
||||
DECL_API("SHGetSpecialFolderLocation", SHGetSpecialFolderLocation_fix),
|
||||
DECL_API("SHGetSpecialFolderPathA", SHGetSpecialFolderPathA_fix),
|
||||
DECL_API("SHGetSpecialFolderPathW", SHGetSpecialFolderPathW_fix),
|
||||
DECL_API("ShellAboutW", ShellAboutW_fwd),
|
||||
DECL_API("ShellExecuteExW", ShellExecuteExW_fwd),
|
||||
DECL_API("ShellExecuteW", ShellExecuteW_fwd),
|
||||
|
5
apilibs/kexbasen/shell32/_shell32_apilist.h
Normal file → Executable file
5
apilibs/kexbasen/shell32/_shell32_apilist.h
Normal file → Executable file
@ -28,9 +28,12 @@ BOOL init_shell32();
|
||||
extern const apilib_api_table apitable_shell32;
|
||||
|
||||
/*** AUTOGENERATED APILIST DECLARATIONS BEGIN ***/
|
||||
HRESULT WINAPI SHGetFolderLocation_new(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwReserved, LPVOID *_ppidl);
|
||||
HRESULT WINAPI SHGetFolderLocation_new(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwReserved, LPVOID *ppidl);
|
||||
HRESULT WINAPI SHGetFolderPathA_new(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPSTR pszPath);
|
||||
HRESULT WINAPI SHGetFolderPathW_new(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath);
|
||||
HRESULT WINAPI SHGetSpecialFolderLocation_fix(HWND hwndOwner, int nFolder, LPVOID *_ppidl);
|
||||
BOOL WINAPI SHGetSpecialFolderPathA_fix(HWND hwndOwner, LPSTR lpszPath, int nFolder, BOOL fCreate);
|
||||
BOOL WINAPI SHGetSpecialFolderPathW_fix(HWND hwndOwner, LPWSTR lpszPath, int nFolder, BOOL fCreate);
|
||||
FWDPROC DragQueryFileW_fwd;
|
||||
FWDPROC ExtractIconExW_fwd;
|
||||
FWDPROC ExtractIconW_fwd;
|
||||
|
@ -1,24 +0,0 @@
|
||||
#ifndef __AUX_SHLGUID_H
|
||||
#define __AUX_SHLGUID_H
|
||||
|
||||
#ifdef DEFINE_GUID
|
||||
#undef DEFINE_GUID
|
||||
#endif
|
||||
|
||||
#define DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
||||
const GUID name \
|
||||
= { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
|
||||
|
||||
DEFINE_GUID(CLSID_NetworkPlaces, 0x208D2C60, 0x3AEA, 0x1069, 0xA2, 0xD7, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D);
|
||||
DEFINE_GUID(CLSID_NetworkDomain, 0x46e06680, 0x4bf0, 0x11d1, 0x83, 0xee, 0x00, 0xa0, 0xc9, 0x0d, 0xc8, 0x49);
|
||||
DEFINE_GUID(CLSID_NetworkServer, 0xc0542a90, 0x4bf0, 0x11d1, 0x83, 0xee, 0x00, 0xa0, 0xc9, 0x0d, 0xc8, 0x49);
|
||||
DEFINE_GUID(CLSID_NetworkShare, 0x54a754c0, 0x4bf0, 0x11d1, 0x83, 0xee, 0x00, 0xa0, 0xc9, 0x0d, 0xc8, 0x49);
|
||||
DEFINE_GUID(CLSID_MyComputer, 0x20D04FE0, 0x3AEA, 0x1069, 0xA2, 0xD8, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D);
|
||||
DEFINE_GUID(CLSID_Internet, 0x871C5380, 0x42A0, 0x1069, 0xA2, 0xEA, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D);
|
||||
DEFINE_GUID(CLSID_ShellFSFolder, 0xF3364BA0, 0x65B9, 0x11CE, 0xA9, 0xBA, 0x00, 0xAA, 0x00, 0x4A, 0xE8, 0x37);
|
||||
DEFINE_GUID(CLSID_RecycleBin, 0x645FF040, 0x5081, 0x101B, 0x9F, 0x08, 0x00, 0xAA, 0x00, 0x2F, 0x95, 0x4E);
|
||||
DEFINE_GUID(CLSID_ControlPanel, 0x21EC2020, 0x3AEA, 0x1069, 0xA2, 0xDD, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D);
|
||||
DEFINE_GUID(CLSID_Printers, 0x2227A280, 0x3AEA, 0x1069, 0xA2, 0xDE, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D);
|
||||
DEFINE_GUID(CLSID_MyDocuments, 0x450d8fba, 0xad25, 0x11d0, 0x98, 0xa8, 0x08, 0x00, 0x36, 0x1b, 0x11, 0x03);
|
||||
|
||||
#endif
|
55
apilibs/kexbasen/shell32/folderfix.h
Executable file
55
apilibs/kexbasen/shell32/folderfix.h
Executable file
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* KernelEx
|
||||
* Copyright (C) 2009, Xeno86
|
||||
*
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
* KernelEx is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* KernelEx is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __FOLDERFIX_H
|
||||
#define __FOLDERFIX_H
|
||||
|
||||
/*
|
||||
* The purpose of the fix is that the Start Menu in Windows 98
|
||||
* and Windows Me don't display any items from "All Users\Start Menu" folder.
|
||||
* Thus the fix is to redirect CSIDL_COMMON_* to approperiate CSIDL_* folders.
|
||||
*
|
||||
* Interesingly Desktop displays icons from "All Users\Desktop"...
|
||||
*
|
||||
* This fix is applied to following functions:
|
||||
* SHGetFolderPathA (both SHELL32 and SHFOLDER)
|
||||
* SHGetFolderPathW (both SHELL32 and SHFOLDER)
|
||||
* SHGetFolderLocation
|
||||
* SHGetSpecialFolderPathA
|
||||
* SHGetSpecialFolderPathW
|
||||
* SHGetSpecialFolderLocation
|
||||
*/
|
||||
|
||||
inline int folder_fix(int nFolder)
|
||||
{
|
||||
int nFolderFlags = nFolder & CSIDL_FLAG_MASK;
|
||||
nFolder &= ~CSIDL_FLAG_MASK;
|
||||
if (nFolder == CSIDL_COMMON_PROGRAMS)
|
||||
nFolder = CSIDL_PROGRAMS;
|
||||
else if (nFolder == CSIDL_COMMON_STARTMENU)
|
||||
nFolder = CSIDL_STARTMENU;
|
||||
else if (nFolder == CSIDL_COMMON_STARTUP)
|
||||
nFolder = CSIDL_STARTUP;
|
||||
nFolder |= nFolderFlags;
|
||||
return nFolder;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,286 +0,0 @@
|
||||
/*
|
||||
* internal pidl functions
|
||||
*
|
||||
* Copyright 1998 Juergen Schmied
|
||||
* Copyright 2004 Juan Lang
|
||||
*
|
||||
* 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
|
||||
*
|
||||
* NOTES:
|
||||
*
|
||||
* DO NOT use this definitions outside the shell32.dll !
|
||||
*
|
||||
* The contents of a pidl should never used from a application
|
||||
* directly.
|
||||
*
|
||||
* Undocumented:
|
||||
* MS says: the abID of SHITEMID should be treated as binary data and not
|
||||
* be interpreted by applications. Applies to everyone but MS itself.
|
||||
* Word95 interprets the contents of abID (Filesize/Date) so we have to go
|
||||
* for binary compatibility here.
|
||||
*/
|
||||
|
||||
#ifndef __WINE_PIDL_H
|
||||
#define __WINE_PIDL_H
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winuser.h"
|
||||
#include "shlobj.h"
|
||||
|
||||
/*
|
||||
* the pidl does cache fileattributes to speed up SHGetAttributes when
|
||||
* displaying a big number of files.
|
||||
*
|
||||
* a pidl of NULL means the desktop
|
||||
*
|
||||
* The structure of the pidl seems to be a union. The first byte of the
|
||||
* PIDLDATA desribes the type of pidl.
|
||||
*
|
||||
* object ! first byte / ! format ! living space
|
||||
* ! size
|
||||
* ----------------------------------------------------------------
|
||||
* my computer 0x1F/20 guid (2) (usual)
|
||||
* network 0x1F guid
|
||||
* bitbucket 0x1F guid
|
||||
* drive 0x23/25 drive (usual)
|
||||
* drive 0x25/25 drive (lnk/persistent)
|
||||
* drive 0x29/25 drive
|
||||
* shell extension 0x2E guid
|
||||
* drive 0x2F drive (lnk/persistent)
|
||||
* folder/file 0x30 folder/file (1) (lnk/persistent)
|
||||
* folder 0x31 folder (usual)
|
||||
* valueA 0x32 file (ANSI file name)
|
||||
* valueW 0x34 file (Unicode file name)
|
||||
* workgroup 0x41 network (3)
|
||||
* computer 0x42 network (4)
|
||||
* net provider 0x46 network
|
||||
* whole network 0x47 network (5)
|
||||
* MSITStore 0x61 htmlhlp (7)
|
||||
* printers/ras connections 0x70 guid
|
||||
* history/favorites 0xb1 file
|
||||
* share 0xc3 network (6)
|
||||
*
|
||||
* guess: the persistent elements are non tracking
|
||||
*
|
||||
* (1) dummy byte is used, attributes are empty
|
||||
* (2) IID_MyComputer = 20D04FE0L-3AEA-1069-A2D8-08002B30309D
|
||||
* (3) two strings "workgroup" "Microsoft Network"
|
||||
* (4) two strings "\\sirius" "Microsoft Network"
|
||||
* (5) one string "Entire Network"
|
||||
* (6) two strings "\\sirius\c" "Microsoft Network"
|
||||
* (7) contains string "mk:@MSITStore:C:\path\file.chm::/path/filename.htm"
|
||||
* GUID 871C5380-42A0-1069-A2EA-08002B30309D
|
||||
*/
|
||||
|
||||
#define PT_CPLAPPLET 0x00
|
||||
#define PT_GUID 0x1F
|
||||
#define PT_DRIVE 0x23
|
||||
#define PT_DRIVE2 0x25
|
||||
#define PT_DRIVE3 0x29
|
||||
#define PT_SHELLEXT 0x2E
|
||||
#define PT_DRIVE1 0x2F
|
||||
#define PT_FOLDER1 0x30
|
||||
#define PT_FOLDER 0x31
|
||||
#define PT_VALUE 0x32
|
||||
#define PT_VALUEW 0x34
|
||||
#define PT_WORKGRP 0x41
|
||||
#define PT_COMP 0x42
|
||||
#define PT_NETPROVIDER 0x46
|
||||
#define PT_NETWORK 0x47
|
||||
#define PT_IESPECIAL1 0x61
|
||||
#define PT_YAGUID 0x70 /* yet another guid.. */
|
||||
#define PT_IESPECIAL2 0xb1
|
||||
#define PT_SHARE 0xc3
|
||||
|
||||
#include "pshpack1.h"
|
||||
typedef BYTE PIDLTYPE;
|
||||
|
||||
typedef struct tagPIDLCPanelStruct
|
||||
{
|
||||
BYTE dummy; /*01 is 0x00 */
|
||||
DWORD iconIdx; /*02 negative icon ID */
|
||||
WORD offsDispName; /*06*/
|
||||
WORD offsComment; /*08*/
|
||||
CHAR szName[1]; /*10*/ /* terminated by 0x00, followed by display name and comment string */
|
||||
} PIDLCPanelStruct;
|
||||
|
||||
typedef struct tagGUIDStruct
|
||||
{
|
||||
BYTE dummy; /* offset 01 is unknown */
|
||||
GUID guid; /* offset 02 */
|
||||
} GUIDStruct;
|
||||
|
||||
typedef struct tagDriveStruct
|
||||
{
|
||||
CHAR szDriveName[20]; /*01*/
|
||||
WORD unknown; /*21*/
|
||||
} DriveStruct;
|
||||
|
||||
typedef struct tagFileStruct
|
||||
{
|
||||
BYTE dummy; /*01 is 0x00 for files or dirs */
|
||||
DWORD dwFileSize; /*02*/
|
||||
WORD uFileDate; /*06*/
|
||||
WORD uFileTime; /*08*/
|
||||
WORD uFileAttribs; /*10*/
|
||||
CHAR szNames[1]; /*12*/
|
||||
/* Here are coming two strings. The first is the long name.
|
||||
The second the dos name when needed or just 0x00 */
|
||||
} FileStruct;
|
||||
|
||||
/* At least on WinXP, this struct is appended with 2-byte-alignment to FileStruct. There follows
|
||||
* a WORD member after the wszName string, which gives the offset from the beginning of the PIDL
|
||||
* to the FileStructW member. */
|
||||
typedef struct tagFileStructW {
|
||||
WORD cbLen;
|
||||
BYTE dummy1[6];
|
||||
WORD uCreationDate;
|
||||
WORD uCreationTime;
|
||||
WORD uLastAccessDate;
|
||||
WORD uLastAccessTime;
|
||||
BYTE dummy2[4];
|
||||
WCHAR wszName[1];
|
||||
} FileStructW;
|
||||
|
||||
typedef struct tagValueW
|
||||
{
|
||||
WCHAR name[1];
|
||||
} ValueWStruct;
|
||||
|
||||
typedef struct tagPIDLDATA
|
||||
{ PIDLTYPE type; /*00*/
|
||||
union
|
||||
{
|
||||
struct tagGUIDStruct guid;
|
||||
struct tagDriveStruct drive;
|
||||
struct tagFileStruct file;
|
||||
struct
|
||||
{ WORD dummy; /*01*/
|
||||
CHAR szNames[1]; /*03*/
|
||||
} network;
|
||||
struct
|
||||
{ WORD dummy; /*01*/
|
||||
DWORD dummy1; /*02*/
|
||||
CHAR szName[1]; /*06*/ /* terminated by 0x00 0x00 */
|
||||
} htmlhelp;
|
||||
struct tagPIDLCPanelStruct cpanel;
|
||||
struct tagValueW valueW;
|
||||
}u;
|
||||
} PIDLDATA, *LPPIDLDATA;
|
||||
#include "poppack.h"
|
||||
|
||||
/*
|
||||
* getting special values from simple pidls
|
||||
*/
|
||||
DWORD _ILSimpleGetText (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize);
|
||||
DWORD _ILSimpleGetTextW (LPCITEMIDLIST pidl, LPWSTR pOut, UINT uOutSize);
|
||||
BOOL _ILGetFileDate (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize);
|
||||
DWORD _ILGetFileSize (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize);
|
||||
BOOL _ILGetExtension (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize);
|
||||
void _ILGetFileType (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize);
|
||||
DWORD _ILGetFileAttributes (LPCITEMIDLIST pidl, LPSTR pOut, UINT uOutSize);
|
||||
|
||||
BOOL _ILGetFileDateTime (LPCITEMIDLIST pidl, FILETIME *ft);
|
||||
DWORD _ILGetDrive (LPCITEMIDLIST, LPSTR, UINT);
|
||||
|
||||
/*
|
||||
* testing simple pidls
|
||||
*/
|
||||
BOOL _ILIsDesktop (LPCITEMIDLIST pidl);
|
||||
BOOL _ILIsMyComputer (LPCITEMIDLIST pidl);
|
||||
BOOL _ILIsDrive (LPCITEMIDLIST pidl);
|
||||
BOOL _ILIsFolder (LPCITEMIDLIST pidl);
|
||||
BOOL _ILIsValue (LPCITEMIDLIST pidl);
|
||||
BOOL _ILIsSpecialFolder (LPCITEMIDLIST pidl);
|
||||
BOOL _ILIsPidlSimple (LPCITEMIDLIST pidl);
|
||||
BOOL _ILIsCPanelStruct (LPCITEMIDLIST pidl);
|
||||
/*
|
||||
static inline
|
||||
BOOL _ILIsEqualSimple (LPCITEMIDLIST pidlA, LPCITEMIDLIST pidlB)
|
||||
{
|
||||
return (pidlA->mkid.cb > 0 && !memcmp(pidlA, pidlB, pidlA->mkid.cb)) ||
|
||||
(!pidlA->mkid.cb && !pidlB->mkid.cb);
|
||||
}
|
||||
static inline
|
||||
BOOL _ILIsEmpty (LPCITEMIDLIST pidl) { return _ILIsDesktop(pidl); }
|
||||
*/
|
||||
|
||||
/*
|
||||
* simple pidls
|
||||
*/
|
||||
|
||||
/* Basic PIDL constructor. Allocates size + 5 bytes, where:
|
||||
* - two bytes are SHITEMID.cb
|
||||
* - one byte is PIDLDATA.type
|
||||
* - two bytes are the NULL PIDL terminator
|
||||
* Sets type of the returned PIDL to type.
|
||||
*/
|
||||
LPITEMIDLIST _ILAlloc(PIDLTYPE type, unsigned int size);
|
||||
|
||||
/* Creates a PIDL with guid format and type type, which must be one of PT_GUID,
|
||||
* PT_SHELLEXT, or PT_YAGUID.
|
||||
*/
|
||||
LPITEMIDLIST _ILCreateGuid(PIDLTYPE type, const IID *guid);
|
||||
|
||||
/* Like _ILCreateGuid, but using the string szGUID. */
|
||||
LPITEMIDLIST _ILCreateGuidFromStrA(LPCSTR szGUID);
|
||||
LPITEMIDLIST _ILCreateGuidFromStrW(LPCWSTR szGUID);
|
||||
|
||||
/* Commonly used PIDLs representing file system objects. */
|
||||
LPITEMIDLIST _ILCreateDesktop (void);
|
||||
LPITEMIDLIST _ILCreateFromFindDataA(WIN32_FIND_DATAA *stffile);
|
||||
LPITEMIDLIST _ILCreateFromFindDataW(WIN32_FIND_DATAW *stffile);
|
||||
HRESULT _ILCreateFromPathA (LPCSTR szPath, LPITEMIDLIST* ppidl);
|
||||
HRESULT _ILCreateFromPathW (LPCWSTR szPath, LPITEMIDLIST* ppidl);
|
||||
|
||||
/* Other helpers */
|
||||
LPITEMIDLIST _ILCreateMyComputer (void);
|
||||
LPITEMIDLIST _ILCreateMyDocuments (void);
|
||||
LPITEMIDLIST _ILCreateIExplore (void);
|
||||
LPITEMIDLIST _ILCreateControlPanel (void);
|
||||
LPITEMIDLIST _ILCreatePrinters (void);
|
||||
LPITEMIDLIST _ILCreateNetwork (void);
|
||||
LPITEMIDLIST _ILCreateBitBucket (void);
|
||||
LPITEMIDLIST _ILCreateDrive (LPCWSTR);
|
||||
|
||||
/*
|
||||
* helper functions (getting struct-pointer)
|
||||
*/
|
||||
LPPIDLDATA _ILGetDataPointer (LPCITEMIDLIST);
|
||||
LPSTR _ILGetTextPointer (LPCITEMIDLIST);
|
||||
LPSTR _ILGetSTextPointer (LPCITEMIDLIST);
|
||||
IID *_ILGetGUIDPointer (LPCITEMIDLIST pidl);
|
||||
FileStructW *_ILGetFileStructW (LPCITEMIDLIST pidl);
|
||||
|
||||
/*
|
||||
* debug helper
|
||||
*/
|
||||
void pdump (LPCITEMIDLIST pidl);
|
||||
BOOL pcheck (LPCITEMIDLIST pidl);
|
||||
|
||||
/*
|
||||
* aPidl helper
|
||||
*/
|
||||
void _ILFreeaPidl(LPITEMIDLIST * apidl, UINT cidl);
|
||||
LPITEMIDLIST * _ILCopyaPidl(LPCITEMIDLIST * apidlsrc, UINT cidl);
|
||||
LPITEMIDLIST * _ILCopyCidaToaPidl(LPITEMIDLIST* pidl, LPIDA cida);
|
||||
|
||||
BOOL WINAPI ILGetDisplayNameExA(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, LPSTR path, DWORD type);
|
||||
BOOL WINAPI ILGetDisplayNameExW(LPSHELLFOLDER psf, LPCITEMIDLIST pidl, LPWSTR path, DWORD type);
|
||||
|
||||
#endif
|
0
apilibs/kexbasen/shell32/unishell32.c
Normal file → Executable file
0
apilibs/kexbasen/shell32/unishell32.c
Normal file → Executable file
13
apilibs/kexbasen/shlwapi/_shlwapi_apilist.c → apilibs/kexbasen/shfolder/_shfolder_apilist.c
Normal file → Executable file
13
apilibs/kexbasen/shlwapi/_shlwapi_apilist.c → apilibs/kexbasen/shfolder/_shfolder_apilist.c
Normal file → Executable file
@ -21,26 +21,27 @@
|
||||
|
||||
#include "common.h"
|
||||
#include "kexcoresdk.h"
|
||||
#include "_shlwapi_apilist.h"
|
||||
#include "_shfolder_apilist.h"
|
||||
|
||||
BOOL init_shlwapi()
|
||||
BOOL init_shfolder()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static const apilib_named_api shlwapi_named_apis[] =
|
||||
static const apilib_named_api shfolder_named_apis[] =
|
||||
{
|
||||
/*** AUTOGENERATED APILIST NAMED EXPORTS BEGIN ***/
|
||||
DECL_API("StrCmpLogicalW", StrCmpLogicalW_new),
|
||||
DECL_API("SHGetFolderPathA", SHFOLDER_SHGetFolderPathA_new),
|
||||
DECL_API("SHGetFolderPathW", SHFOLDER_SHGetFolderPathW_new),
|
||||
/*** AUTOGENERATED APILIST NAMED EXPORTS END ***/
|
||||
};
|
||||
|
||||
#if 0
|
||||
static const apilib_unnamed_api shlwapi_ordinal_apis[] =
|
||||
static const apilib_unnamed_api shfolder_ordinal_apis[] =
|
||||
{
|
||||
/*** AUTOGENERATED APILIST ORDINAL EXPORTS BEGIN ***/
|
||||
/*** AUTOGENERATED APILIST ORDINAL EXPORTS END ***/
|
||||
};
|
||||
#endif
|
||||
|
||||
const apilib_api_table apitable_shlwapi = DECL_TAB("SHLWAPI.DLL", shlwapi_named_apis, 0 /*shlwapi_ordinal_apis*/);
|
||||
const apilib_api_table apitable_shfolder = DECL_TAB("SHFOLDER.DLL", shfolder_named_apis, 0 /*shfolder_ordinal_apis*/);
|
11
apilibs/kexbasen/shlwapi/_shlwapi_apilist.h → apilibs/kexbasen/shfolder/_shfolder_apilist.h
Normal file → Executable file
11
apilibs/kexbasen/shlwapi/_shlwapi_apilist.h → apilibs/kexbasen/shfolder/_shfolder_apilist.h
Normal file → Executable file
@ -19,16 +19,17 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _SHLWAPI_APILIST_H
|
||||
#define _SHLWAPI_APILIST_H
|
||||
#ifndef _SHFOLDER_APILIST_H
|
||||
#define _SHFOLDER_APILIST_H
|
||||
|
||||
#include "kexcoresdk.h"
|
||||
|
||||
BOOL init_shlwapi();
|
||||
extern const apilib_api_table apitable_shlwapi;
|
||||
BOOL init_shfolder();
|
||||
extern const apilib_api_table apitable_shfolder;
|
||||
|
||||
/*** AUTOGENERATED APILIST DECLARATIONS BEGIN ***/
|
||||
INT WINAPI StrCmpLogicalW_new(LPCWSTR lpszStr, LPCWSTR lpszComp);
|
||||
HRESULT WINAPI SHFOLDER_SHGetFolderPathA_new(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPSTR pszPath);
|
||||
HRESULT WINAPI SHFOLDER_SHGetFolderPathW_new(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath);
|
||||
/*** AUTOGENERATED APILIST DECLARATIONS END ***/
|
||||
|
||||
#endif
|
36
apilibs/kexbasen/shfolder/shfolder.c
Executable file
36
apilibs/kexbasen/shfolder/shfolder.c
Executable file
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* KernelEx
|
||||
* Copyright (C) 2009, Xeno86
|
||||
*
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
* KernelEx is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* KernelEx is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include "common.h"
|
||||
#include "../shell32/_shell32_apilist.h"
|
||||
|
||||
/* MAKE_EXPORT SHFOLDER_SHGetFolderPathA_new=SHGetFolderPathA */
|
||||
HRESULT WINAPI SHFOLDER_SHGetFolderPathA_new(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPSTR pszPath)
|
||||
{
|
||||
return SHGetFolderPathA_new(hwndOwner, nFolder, hToken, dwFlags, pszPath);
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT SHFOLDER_SHGetFolderPathW_new=SHGetFolderPathW */
|
||||
HRESULT WINAPI SHFOLDER_SHGetFolderPathW_new(HWND hwndOwner, int nFolder, HANDLE hToken, DWORD dwFlags, LPWSTR pszPath)
|
||||
{
|
||||
return SHGetFolderPathW_new(hwndOwner, nFolder, hToken, dwFlags, pszPath);
|
||||
}
|
57
apilibs/kexbases/Gdi32/gdi9x.h → apilibs/kexbasen/shlord.c
Normal file → Executable file
57
apilibs/kexbases/Gdi32/gdi9x.h → apilibs/kexbasen/shlord.c
Normal file → Executable file
@ -1,7 +1,7 @@
|
||||
/*
|
||||
* KernelEx
|
||||
*
|
||||
* Copyright (C) 2009, Tihiy
|
||||
*
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
* KernelEx is free software; you can redistribute it and/or modify
|
||||
@ -19,41 +19,30 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GDI9X_H
|
||||
#define __GDI9X_H
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include "shlord.h"
|
||||
#include "common.h"
|
||||
|
||||
#define LHE_DISCARDED 0x40
|
||||
#define LHE_FREEHANDLE 0xFF
|
||||
static HMODULE hShlwapi;
|
||||
|
||||
#define GDI_OBJTYPE_MASK 0x5FFF
|
||||
#define GDI_OBJTYPE_DC 0x4F4D
|
||||
#define GDI_OBJTYPE_DC_NO 0x4F4E
|
||||
|
||||
#define ResetMapMode( hdc ) SetMapMode( hdc, GetMapMode(hdc) )
|
||||
|
||||
#pragma pack(push,1)
|
||||
|
||||
typedef struct
|
||||
void shlwapi_fatal_error(int funcnum)
|
||||
{
|
||||
WORD wBlock;
|
||||
BYTE bFlags;
|
||||
BYTE bLocks;
|
||||
} LHENTRY, *PLHENTRY;
|
||||
char msg[256];
|
||||
sprintf(msg, "kexbasen: Failed to get shlwapi proc: #%i",funcnum);
|
||||
fatal_error(msg);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
PVOID WINAPI GetShlwapiProc(int funcnum)
|
||||
{
|
||||
WORD wZero; //+0
|
||||
WORD wType; //+2
|
||||
BYTE filler[0x80]; //+4
|
||||
WORD WindowExtX; //+84
|
||||
WORD WindowExtY; //+86
|
||||
BYTE filler2[4]; //+88
|
||||
WORD ViewportExtX; //+8C
|
||||
WORD ViewportExtY; //+8E
|
||||
BYTE filler3[4]; //+90
|
||||
WORD mapmode; //+94
|
||||
} DCOBJ, *PDCOBJ;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
||||
if (!hShlwapi)
|
||||
{
|
||||
hShlwapi = GetModuleHandle("shlwapi.dll");
|
||||
if (!hShlwapi)
|
||||
hShlwapi = LoadLibrary("shlwapi.dll");
|
||||
}
|
||||
PVOID proc = GetProcAddress(hShlwapi,(LPSTR)funcnum);
|
||||
if (!proc)
|
||||
shlwapi_fatal_error(funcnum);
|
||||
return proc;
|
||||
}
|
27
apilibs/kexbasen/shlord.h
Executable file
27
apilibs/kexbasen/shlord.h
Executable file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* KernelEx
|
||||
* Copyright (C) 2008, Xeno86
|
||||
*
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
* KernelEx is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* KernelEx is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __SHLORD_H
|
||||
#define __SHLORD_H
|
||||
|
||||
PVOID WINAPI GetShlwapiProc(int funcnum);
|
||||
|
||||
#endif
|
@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Shlwapi string functions
|
||||
*
|
||||
* Copyright 1998 Juergen Schmied
|
||||
* Copyright 2002 Jon Griffiths
|
||||
*
|
||||
* 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 <windows.h>
|
||||
#pragma warning(disable:4002)
|
||||
#define TRACE()
|
||||
|
||||
EXTERN_C DECLSPEC_IMPORT BOOL WINAPI StrToIntExW(LPCWSTR lpszStr, DWORD dwFlags, LPINT lpiRet);
|
||||
EXTERN_C DECLSPEC_IMPORT BOOL WINAPI ChrCmpIW(WCHAR ch1, WCHAR ch2);
|
||||
|
||||
static int isdigitW(WCHAR wc)
|
||||
{
|
||||
if (wc >= '0' && wc <= '9')
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* StrCmpLogicalW [SHLWAPI.@]
|
||||
*
|
||||
* Compare two strings, ignoring case and comparing digits as numbers.
|
||||
*
|
||||
* PARAMS
|
||||
* lpszStr [I] First string to compare
|
||||
* lpszComp [I] Second string to compare
|
||||
* iLen [I] Length to compare
|
||||
*
|
||||
* RETURNS
|
||||
* TRUE If the strings are equal.
|
||||
* FALSE Otherwise.
|
||||
*/
|
||||
/* MAKE_EXPORT StrCmpLogicalW_new=StrCmpLogicalW */
|
||||
INT WINAPI StrCmpLogicalW_new(LPCWSTR lpszStr, LPCWSTR lpszComp)
|
||||
{
|
||||
INT iDiff;
|
||||
|
||||
TRACE("(%s,%s)\n", debugstr_w(lpszStr), debugstr_w(lpszComp));
|
||||
|
||||
if (lpszStr && lpszComp)
|
||||
{
|
||||
while (*lpszStr)
|
||||
{
|
||||
if (!*lpszComp)
|
||||
return 1;
|
||||
else if (isdigitW(*lpszStr))
|
||||
{
|
||||
int iStr, iComp;
|
||||
|
||||
if (!isdigitW(*lpszComp))
|
||||
return -1;
|
||||
|
||||
/* Compare the numbers */
|
||||
StrToIntExW(lpszStr, 0, &iStr);
|
||||
StrToIntExW(lpszComp, 0, &iComp);
|
||||
|
||||
if (iStr < iComp)
|
||||
return -1;
|
||||
else if (iStr > iComp)
|
||||
return 1;
|
||||
|
||||
/* Skip */
|
||||
while (isdigitW(*lpszStr))
|
||||
lpszStr++;
|
||||
while (isdigitW(*lpszComp))
|
||||
lpszComp++;
|
||||
}
|
||||
else if (isdigitW(*lpszComp))
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
iDiff = ChrCmpIW(*lpszStr,*lpszComp);
|
||||
if (iDiff > 0)
|
||||
return 1;
|
||||
else if (iDiff < 0)
|
||||
return -1;
|
||||
|
||||
lpszStr++;
|
||||
lpszComp++;
|
||||
}
|
||||
}
|
||||
if (*lpszComp)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
0
apilibs/kexbasen/unifwd.c
Normal file → Executable file
0
apilibs/kexbasen/unifwd.c
Normal file → Executable file
0
apilibs/kexbasen/unifwd.h
Normal file → Executable file
0
apilibs/kexbasen/unifwd.h
Normal file → Executable file
35
apilibs/kexbasen/user32/_user32_apilist.c
Normal file → Executable file
35
apilibs/kexbasen/user32/_user32_apilist.c
Normal file → Executable file
@ -33,23 +33,12 @@ static const apilib_named_api user32_named_apis[] =
|
||||
/*** AUTOGENERATED APILIST NAMED EXPORTS BEGIN ***/
|
||||
DECL_API("AppendMenuW", AppendMenuW_fwd),
|
||||
DECL_API("BroadcastSystemMessageW", BroadcastSystemMessageW_fwd),
|
||||
DECL_API("CallWindowProcW", CallWindowProcW_fwd),
|
||||
DECL_API("ChangeDisplaySettingsExW", ChangeDisplaySettingsExW_fwd),
|
||||
DECL_API("ChangeDisplaySettingsW", ChangeDisplaySettingsW_fwd),
|
||||
DECL_API("ChangeMenuW", ChangeMenuW_fwd),
|
||||
DECL_API("CreateDialogIndirectParamW", CreateDialogIndirectParamW_fwd),
|
||||
DECL_API("CreateDialogParamW", CreateDialogParamW_new),
|
||||
DECL_API("CreateMDIWindowW", CreateMDIWindowW_fwd),
|
||||
DECL_API("CreateWindowExW", CreateWindowExW_fwd),
|
||||
DECL_API("DdeCreateStringHandleW", DdeCreateStringHandleW_fwd),
|
||||
DECL_API("DdeInitializeW", DdeInitializeW_fwd),
|
||||
DECL_API("DdeQueryStringW", DdeQueryStringW_fwd),
|
||||
DECL_API("DefDlgProcW", DefDlgProcW_fwd),
|
||||
DECL_API("DefFrameProcW", DefFrameProcW_fwd),
|
||||
DECL_API("DefMDIChildProcW", DefMDIChildProcW_fwd),
|
||||
DECL_API("DefWindowProcW", DefWindowProcW_new),
|
||||
DECL_API("DialogBoxIndirectParamW", DialogBoxIndirectParamW_fwd),
|
||||
DECL_API("DialogBoxParamW", DialogBoxParamW_fwd),
|
||||
DECL_API("DlgDirListComboBoxW", DlgDirListComboBoxW_fwd),
|
||||
DECL_API("DlgDirListW", DlgDirListW_fwd),
|
||||
DECL_API("DlgDirSelectComboBoxExW", DlgDirSelectComboBoxExW_fwd),
|
||||
@ -65,12 +54,8 @@ static const apilib_named_api user32_named_apis[] =
|
||||
DECL_API("FindWindowExW", FindWindowExW_fwd),
|
||||
DECL_API("FindWindowW", FindWindowW_fwd),
|
||||
DECL_API("GetAltTabInfoW", GetAltTabInfoW_fwd),
|
||||
DECL_API("GetClassInfoExW", GetClassInfoExW_fwd),
|
||||
DECL_API("GetClassInfoW", GetClassInfoW_fwd),
|
||||
DECL_API("GetClassLongW", GetClassLongW_fwd),
|
||||
DECL_API("GetClassNameW", GetClassNameW_fwd),
|
||||
DECL_API("GetClipboardFormatNameW", GetClipboardFormatNameW_fwd),
|
||||
DECL_API("GetDlgItemTextW", GetDlgItemTextW_fwd),
|
||||
DECL_API("GetKeyNameTextW", GetKeyNameTextW_fwd),
|
||||
DECL_API("GetKeyboardLayoutNameW", GetKeyboardLayoutNameW_fwd),
|
||||
DECL_API("GetMenuItemInfoW", GetMenuItemInfoW_fwd),
|
||||
@ -78,13 +63,9 @@ static const apilib_named_api user32_named_apis[] =
|
||||
DECL_API("GetMonitorInfoW", GetMonitorInfoW_fwd),
|
||||
DECL_API("GetPropW", GetPropW_fwd),
|
||||
DECL_API("GetTabbedTextExtentW", GetTabbedTextExtentW_fwd),
|
||||
DECL_API("GetWindowLongW", GetWindowLongW_fwd),
|
||||
DECL_API("GetWindowTextLengthW", GetWindowTextLengthW_fwd),
|
||||
DECL_API("GetWindowTextW", GetWindowTextW_fwd),
|
||||
DECL_API("GrayStringW", GrayStringW_fwd),
|
||||
DECL_API("InsertMenuItemW", InsertMenuItemW_fwd),
|
||||
DECL_API("InsertMenuW", InsertMenuW_fwd),
|
||||
DECL_API("IsWindowUnicode", IsWindowUnicode_fwd),
|
||||
DECL_API("LoadAcceleratorsW", LoadAcceleratorsW_fwd),
|
||||
DECL_API("LoadBitmapW", LoadBitmapW_fwd),
|
||||
DECL_API("LoadCursorFromFileW", LoadCursorFromFileW_fwd),
|
||||
@ -98,30 +79,14 @@ static const apilib_named_api user32_named_apis[] =
|
||||
DECL_API("MapVirtualKeyW", MapVirtualKeyW_fwd),
|
||||
DECL_API("MessageBoxIndirectW", MessageBoxIndirectW_fwd),
|
||||
DECL_API("ModifyMenuW", ModifyMenuW_fwd),
|
||||
DECL_API("PostMessageW", PostMessageW_fwd),
|
||||
DECL_API("PostThreadMessageW", PostThreadMessageW_fwd),
|
||||
DECL_API("RegisterClassExW", RegisterClassExW_fwd),
|
||||
DECL_API("RegisterClassW", RegisterClassW_fwd),
|
||||
DECL_API("RegisterClipboardFormatW", RegisterClipboardFormatW_fwd),
|
||||
DECL_API("RegisterDeviceNotificationW", RegisterDeviceNotificationW_fwd),
|
||||
DECL_API("RegisterWindowMessageW", RegisterWindowMessageW_fwd),
|
||||
DECL_API("RemovePropW", RemovePropW_fwd),
|
||||
DECL_API("SendDlgItemMessageW", SendDlgItemMessageW_fwd),
|
||||
DECL_API("SendMessageCallbackW", SendMessageCallbackW_fwd),
|
||||
DECL_API("SendMessageTimeoutW", SendMessageTimeoutW_fwd),
|
||||
DECL_API("SendMessageW", SendMessageW_fwd),
|
||||
DECL_API("SendNotifyMessageW", SendNotifyMessageW_fwd),
|
||||
DECL_API("SetClassLongW", SetClassLongW_fwd),
|
||||
DECL_API("SetDlgItemTextW", SetDlgItemTextW_fwd),
|
||||
DECL_API("SetMenuItemInfoW", SetMenuItemInfoW_fwd),
|
||||
DECL_API("SetPropW", SetPropW_fwd),
|
||||
DECL_API("SetWindowLongW", SetWindowLongW_fwd),
|
||||
DECL_API("SetWindowTextW", SetWindowTextW_fwd),
|
||||
DECL_API("SetWindowsHookExW", SetWindowsHookExW_fwd),
|
||||
DECL_API("SetWindowsHookW", SetWindowsHookW_fwd),
|
||||
DECL_API("SystemParametersInfoW", SystemParametersInfoW_fwd),
|
||||
DECL_API("TabbedTextOutW", TabbedTextOutW_fwd),
|
||||
DECL_API("UnregisterClassW", UnregisterClassW_fwd),
|
||||
DECL_API("VkKeyScanExW", VkKeyScanExW_fwd),
|
||||
DECL_API("VkKeyScanW", VkKeyScanW_fwd),
|
||||
DECL_API("WinHelpW", WinHelpW_fwd),
|
||||
|
35
apilibs/kexbasen/user32/_user32_apilist.h
Normal file → Executable file
35
apilibs/kexbasen/user32/_user32_apilist.h
Normal file → Executable file
@ -30,21 +30,12 @@ extern const apilib_api_table apitable_user32;
|
||||
/*** AUTOGENERATED APILIST DECLARATIONS BEGIN ***/
|
||||
FWDPROC AppendMenuW_fwd;
|
||||
FWDPROC BroadcastSystemMessageW_fwd;
|
||||
FWDPROC CallWindowProcW_fwd;
|
||||
FWDPROC ChangeDisplaySettingsExW_fwd;
|
||||
FWDPROC ChangeDisplaySettingsW_fwd;
|
||||
FWDPROC ChangeMenuW_fwd;
|
||||
FWDPROC CreateDialogIndirectParamW_fwd;
|
||||
FWDPROC CreateMDIWindowW_fwd;
|
||||
FWDPROC CreateWindowExW_fwd;
|
||||
FWDPROC DdeCreateStringHandleW_fwd;
|
||||
FWDPROC DdeInitializeW_fwd;
|
||||
FWDPROC DdeQueryStringW_fwd;
|
||||
FWDPROC DefDlgProcW_fwd;
|
||||
FWDPROC DefFrameProcW_fwd;
|
||||
FWDPROC DefMDIChildProcW_fwd;
|
||||
FWDPROC DialogBoxIndirectParamW_fwd;
|
||||
FWDPROC DialogBoxParamW_fwd;
|
||||
FWDPROC DlgDirListComboBoxW_fwd;
|
||||
FWDPROC DlgDirListW_fwd;
|
||||
FWDPROC DlgDirSelectComboBoxExW_fwd;
|
||||
@ -60,12 +51,8 @@ FWDPROC EnumPropsW_fwd;
|
||||
FWDPROC FindWindowExW_fwd;
|
||||
FWDPROC FindWindowW_fwd;
|
||||
FWDPROC GetAltTabInfoW_fwd;
|
||||
FWDPROC GetClassInfoExW_fwd;
|
||||
FWDPROC GetClassInfoW_fwd;
|
||||
FWDPROC GetClassLongW_fwd;
|
||||
FWDPROC GetClassNameW_fwd;
|
||||
FWDPROC GetClipboardFormatNameW_fwd;
|
||||
FWDPROC GetDlgItemTextW_fwd;
|
||||
FWDPROC GetKeyboardLayoutNameW_fwd;
|
||||
FWDPROC GetKeyNameTextW_fwd;
|
||||
FWDPROC GetMenuItemInfoW_fwd;
|
||||
@ -73,13 +60,9 @@ FWDPROC GetMenuStringW_fwd;
|
||||
FWDPROC GetMonitorInfoW_fwd;
|
||||
FWDPROC GetPropW_fwd;
|
||||
FWDPROC GetTabbedTextExtentW_fwd;
|
||||
FWDPROC GetWindowLongW_fwd;
|
||||
FWDPROC GetWindowTextLengthW_fwd;
|
||||
FWDPROC GetWindowTextW_fwd;
|
||||
FWDPROC GrayStringW_fwd;
|
||||
FWDPROC InsertMenuItemW_fwd;
|
||||
FWDPROC InsertMenuW_fwd;
|
||||
FWDPROC IsWindowUnicode_fwd;
|
||||
FWDPROC LoadAcceleratorsW_fwd;
|
||||
FWDPROC LoadBitmapW_fwd;
|
||||
FWDPROC LoadCursorFromFileW_fwd;
|
||||
@ -93,37 +76,19 @@ FWDPROC MapVirtualKeyExW_fwd;
|
||||
FWDPROC MapVirtualKeyW_fwd;
|
||||
FWDPROC MessageBoxIndirectW_fwd;
|
||||
FWDPROC ModifyMenuW_fwd;
|
||||
FWDPROC PostMessageW_fwd;
|
||||
FWDPROC PostThreadMessageW_fwd;
|
||||
FWDPROC RegisterClassExW_fwd;
|
||||
FWDPROC RegisterClassW_fwd;
|
||||
FWDPROC RegisterClipboardFormatW_fwd;
|
||||
FWDPROC RegisterDeviceNotificationW_fwd;
|
||||
FWDPROC RegisterWindowMessageW_fwd;
|
||||
FWDPROC RemovePropW_fwd;
|
||||
FWDPROC SendDlgItemMessageW_fwd;
|
||||
FWDPROC SendMessageCallbackW_fwd;
|
||||
FWDPROC SendMessageTimeoutW_fwd;
|
||||
FWDPROC SendMessageW_fwd;
|
||||
FWDPROC SendNotifyMessageW_fwd;
|
||||
FWDPROC SetClassLongW_fwd;
|
||||
FWDPROC SetDlgItemTextW_fwd;
|
||||
FWDPROC SetMenuItemInfoW_fwd;
|
||||
FWDPROC SetPropW_fwd;
|
||||
FWDPROC SetWindowLongW_fwd;
|
||||
FWDPROC SetWindowsHookExW_fwd;
|
||||
FWDPROC SetWindowsHookW_fwd;
|
||||
FWDPROC SetWindowTextW_fwd;
|
||||
FWDPROC SystemParametersInfoW_fwd;
|
||||
FWDPROC TabbedTextOutW_fwd;
|
||||
FWDPROC UnregisterClassW_fwd;
|
||||
FWDPROC VkKeyScanExW_fwd;
|
||||
FWDPROC VkKeyScanW_fwd;
|
||||
FWDPROC WinHelpW_fwd;
|
||||
FWDPROC wsprintfW_fwd;
|
||||
FWDPROC wvsprintfW_fwd;
|
||||
HWND WINAPI CreateDialogParamW_new(HINSTANCE hInstance, LPCSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam);
|
||||
LRESULT WINAPI DefWindowProcW_new(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
|
||||
/*** AUTOGENERATED APILIST DECLARATIONS END ***/
|
||||
|
||||
#endif
|
||||
|
62
apilibs/kexbasen/user32/uniuser32.c
Normal file → Executable file
62
apilibs/kexbasen/user32/uniuser32.c
Normal file → Executable file
@ -25,50 +25,12 @@
|
||||
|
||||
FORWARD_TO_UNICOWS(AppendMenuW);
|
||||
FORWARD_TO_UNICOWS(BroadcastSystemMessageW);
|
||||
FORWARD_TO_UNICOWS(CallWindowProcW);
|
||||
FORWARD_TO_UNICOWS(ChangeDisplaySettingsExW);
|
||||
FORWARD_TO_UNICOWS(ChangeDisplaySettingsW);
|
||||
FORWARD_TO_UNICOWS(ChangeMenuW);
|
||||
FORWARD_TO_UNICOWS(CreateDialogIndirectParamW);
|
||||
|
||||
static BOOL CALLBACK SetUnicode(HWND hwnd, LPARAM lParam)
|
||||
{
|
||||
return SendMessage(hwnd, CCM_SETUNICODEFORMAT, TRUE, 0);
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT CreateDialogParamW_new=CreateDialogParamW */
|
||||
HWND WINAPI CreateDialogParamW_new(HINSTANCE hInstance, LPCSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam)
|
||||
{
|
||||
typedef HWND (WINAPI *CreateDialogParamW_t)(HINSTANCE, LPCSTR, HWND, DLGPROC, LPARAM);
|
||||
static CreateDialogParamW_t g_DialogParamW;
|
||||
HWND hDlg;
|
||||
if (!g_DialogParamW) g_DialogParamW = (CreateDialogParamW_t) GetUnicowsAddress("CreateDialogParamW");
|
||||
hDlg = g_DialogParamW(hInstance, lpTemplateName, hWndParent, lpDialogFunc, dwInitParam);
|
||||
if (hDlg) EnumChildWindows(hDlg, SetUnicode, 0);
|
||||
return hDlg;
|
||||
}
|
||||
|
||||
FORWARD_TO_UNICOWS(CreateMDIWindowW);
|
||||
FORWARD_TO_UNICOWS(CreateWindowExW);
|
||||
FORWARD_TO_UNICOWS(DdeCreateStringHandleW);
|
||||
FORWARD_TO_UNICOWS(DdeInitializeW);
|
||||
FORWARD_TO_UNICOWS(DdeQueryStringW);
|
||||
FORWARD_TO_UNICOWS(DefDlgProcW);
|
||||
FORWARD_TO_UNICOWS(DefFrameProcW);
|
||||
FORWARD_TO_UNICOWS(DefMDIChildProcW);
|
||||
|
||||
/* MAKE_EXPORT DefWindowProcW_new=DefWindowProcW */
|
||||
LRESULT WINAPI DefWindowProcW_new(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
typedef LRESULT (WINAPI *DefWindowProcW_t)(HWND, UINT, WPARAM, LPARAM);
|
||||
static DefWindowProcW_t g_DefProcW;
|
||||
if (!g_DefProcW) g_DefProcW = (DefWindowProcW_t) GetUnicowsAddress("DefWindowProcW");
|
||||
if (Msg == WM_NOTIFYFORMAT && lParam == NF_QUERY && IsWindowUnicode(hWnd)) return NFR_UNICODE;
|
||||
return g_DefProcW(hWnd, Msg, wParam, lParam);
|
||||
}
|
||||
|
||||
FORWARD_TO_UNICOWS(DialogBoxIndirectParamW);
|
||||
FORWARD_TO_UNICOWS(DialogBoxParamW);
|
||||
FORWARD_TO_UNICOWS(DlgDirListComboBoxW);
|
||||
FORWARD_TO_UNICOWS(DlgDirListW);
|
||||
FORWARD_TO_UNICOWS(DlgDirSelectComboBoxExW);
|
||||
@ -84,12 +46,8 @@ FORWARD_TO_UNICOWS(EnumPropsW);
|
||||
FORWARD_TO_UNICOWS(FindWindowExW);
|
||||
FORWARD_TO_UNICOWS(FindWindowW);
|
||||
FORWARD_TO_UNICOWS(GetAltTabInfoW);
|
||||
FORWARD_TO_UNICOWS(GetClassInfoExW);
|
||||
FORWARD_TO_UNICOWS(GetClassInfoW);
|
||||
FORWARD_TO_UNICOWS(GetClassLongW);
|
||||
FORWARD_TO_UNICOWS(GetClassNameW);
|
||||
FORWARD_TO_UNICOWS(GetClipboardFormatNameW);
|
||||
FORWARD_TO_UNICOWS(GetDlgItemTextW);
|
||||
FORWARD_TO_UNICOWS(GetKeyboardLayoutNameW);
|
||||
FORWARD_TO_UNICOWS(GetKeyNameTextW);
|
||||
FORWARD_TO_UNICOWS(GetMenuItemInfoW);
|
||||
@ -97,13 +55,9 @@ FORWARD_TO_UNICOWS(GetMenuStringW);
|
||||
FORWARD_TO_UNICOWS(GetMonitorInfoW);
|
||||
FORWARD_TO_UNICOWS(GetPropW);
|
||||
FORWARD_TO_UNICOWS(GetTabbedTextExtentW);
|
||||
FORWARD_TO_UNICOWS(GetWindowLongW);
|
||||
FORWARD_TO_UNICOWS(GetWindowTextLengthW);
|
||||
FORWARD_TO_UNICOWS(GetWindowTextW);
|
||||
FORWARD_TO_UNICOWS(GrayStringW);
|
||||
FORWARD_TO_UNICOWS(InsertMenuItemW);
|
||||
FORWARD_TO_UNICOWS(InsertMenuW);
|
||||
FORWARD_TO_UNICOWS(IsWindowUnicode);
|
||||
FORWARD_TO_UNICOWS(LoadAcceleratorsW);
|
||||
FORWARD_TO_UNICOWS(LoadBitmapW);
|
||||
FORWARD_TO_UNICOWS(LoadCursorFromFileW);
|
||||
@ -117,30 +71,14 @@ FORWARD_TO_UNICOWS(MapVirtualKeyExW);
|
||||
FORWARD_TO_UNICOWS(MapVirtualKeyW);
|
||||
FORWARD_TO_UNICOWS(MessageBoxIndirectW);
|
||||
FORWARD_TO_UNICOWS(ModifyMenuW);
|
||||
FORWARD_TO_UNICOWS(PostMessageW);
|
||||
FORWARD_TO_UNICOWS(PostThreadMessageW);
|
||||
FORWARD_TO_UNICOWS(RegisterClassExW);
|
||||
FORWARD_TO_UNICOWS(RegisterClassW);
|
||||
FORWARD_TO_UNICOWS(RegisterClipboardFormatW);
|
||||
FORWARD_TO_UNICOWS(RegisterDeviceNotificationW);
|
||||
FORWARD_TO_UNICOWS(RegisterWindowMessageW);
|
||||
FORWARD_TO_UNICOWS(RemovePropW);
|
||||
FORWARD_TO_UNICOWS(SendDlgItemMessageW);
|
||||
FORWARD_TO_UNICOWS(SendMessageCallbackW);
|
||||
FORWARD_TO_UNICOWS(SendMessageTimeoutW);
|
||||
FORWARD_TO_UNICOWS(SendMessageW);
|
||||
FORWARD_TO_UNICOWS(SendNotifyMessageW);
|
||||
FORWARD_TO_UNICOWS(SetClassLongW);
|
||||
FORWARD_TO_UNICOWS(SetDlgItemTextW);
|
||||
FORWARD_TO_UNICOWS(SetMenuItemInfoW);
|
||||
FORWARD_TO_UNICOWS(SetPropW);
|
||||
FORWARD_TO_UNICOWS(SetWindowLongW);
|
||||
FORWARD_TO_UNICOWS(SetWindowsHookExW);
|
||||
FORWARD_TO_UNICOWS(SetWindowsHookW);
|
||||
FORWARD_TO_UNICOWS(SetWindowTextW);
|
||||
FORWARD_TO_UNICOWS(SystemParametersInfoW);
|
||||
FORWARD_TO_UNICOWS(TabbedTextOutW);
|
||||
FORWARD_TO_UNICOWS(UnregisterClassW);
|
||||
FORWARD_TO_UNICOWS(VkKeyScanExW);
|
||||
FORWARD_TO_UNICOWS(VkKeyScanW);
|
||||
FORWARD_TO_UNICOWS(WinHelpW);
|
||||
|
3
apilibs/kexbasen/winspool/DefaultPrinter.c
Normal file → Executable file
3
apilibs/kexbasen/winspool/DefaultPrinter.c
Normal file → Executable file
@ -63,7 +63,8 @@ BOOL WINAPI GetDefaultPrinterW(LPWSTR bufW, LPDWORD sizeW)
|
||||
if (ret)
|
||||
{
|
||||
*sizeW = ABUFtoW(buf, sizeA, *sizeW);
|
||||
if (!ret)
|
||||
if (*sizeW)
|
||||
return TRUE;
|
||||
*sizeW = ABUFtoW(buf, sizeA, 0);
|
||||
}
|
||||
return FALSE;
|
||||
|
28
apilibs/kexbasen/winspool/_winspool_apilist.c
Normal file → Executable file
28
apilibs/kexbasen/winspool/_winspool_apilist.c
Normal file → Executable file
@ -31,8 +31,36 @@ BOOL init_winspool()
|
||||
static const apilib_named_api winspool_named_apis[] =
|
||||
{
|
||||
/*** AUTOGENERATED APILIST NAMED EXPORTS BEGIN ***/
|
||||
DECL_API("AddJobW", AddJobW_fwd),
|
||||
DECL_API("AddMonitorW", AddMonitorW_fwd),
|
||||
DECL_API("AddPortW", AddPortW_fwd),
|
||||
DECL_API("AddPrintProcessorW", AddPrintProcessorW_fwd),
|
||||
DECL_API("AddPrintProvidorW", AddPrintProvidorW_fwd),
|
||||
DECL_API("AddPrinterDriverW", AddPrinterDriverW_fwd),
|
||||
DECL_API("AddPrinterW", AddPrinterW_fwd),
|
||||
DECL_API("AdvancedDocumentPropertiesW", AdvancedDocumentPropertiesW_fwd),
|
||||
DECL_API("ConfigurePortW", ConfigurePortW_fwd),
|
||||
DECL_API("DeleteMonitorW", DeleteMonitorW_fwd),
|
||||
DECL_API("DeletePortW", DeletePortW_fwd),
|
||||
DECL_API("DeletePrintProcessorW", DeletePrintProcessorW_fwd),
|
||||
DECL_API("DeletePrintProvidorW", DeletePrintProvidorW_fwd),
|
||||
DECL_API("DeletePrinterDriverW", DeletePrinterDriverW_fwd),
|
||||
DECL_API("DeviceCapabilitiesW", DeviceCapabilitiesW_fwd),
|
||||
DECL_API("DocumentPropertiesW", DocumentPropertiesW_fwd),
|
||||
DECL_API("GetDefaultPrinterA", GetDefaultPrinterA),
|
||||
DECL_API("GetDefaultPrinterW", GetDefaultPrinterW),
|
||||
DECL_API("GetPrintProcessorDirectoryW", GetPrintProcessorDirectoryW_fwd),
|
||||
DECL_API("GetPrinterDataExA", GetPrinterDataExA_stub),
|
||||
DECL_API("GetPrinterDataExW", GetPrinterDataExW_stub),
|
||||
DECL_API("GetPrinterDriverDirectoryW", GetPrinterDriverDirectoryW_fwd),
|
||||
DECL_API("OpenPrinterW", OpenPrinterW_fwd),
|
||||
DECL_API("ResetPrinterW", ResetPrinterW_fwd),
|
||||
DECL_API("SetJobW", SetJobW_fwd),
|
||||
DECL_API("SetPrinterDataExA", SetPrinterDataExA_stub),
|
||||
DECL_API("SetPrinterDataExW", SetPrinterDataExW_stub),
|
||||
DECL_API("SetPrinterDataW", SetPrinterDataW_fwd),
|
||||
DECL_API("SetPrinterW", SetPrinterW_fwd),
|
||||
DECL_API("StartDocPrinterW", StartDocPrinterW_fwd),
|
||||
/*** AUTOGENERATED APILIST NAMED EXPORTS END ***/
|
||||
};
|
||||
|
||||
|
28
apilibs/kexbasen/winspool/_winspool_apilist.h
Normal file → Executable file
28
apilibs/kexbasen/winspool/_winspool_apilist.h
Normal file → Executable file
@ -30,6 +30,34 @@ extern const apilib_api_table apitable_winspool;
|
||||
/*** AUTOGENERATED APILIST DECLARATIONS BEGIN ***/
|
||||
BOOL WINAPI GetDefaultPrinterA(LPSTR buf, LPDWORD size);
|
||||
BOOL WINAPI GetDefaultPrinterW(LPWSTR bufW, LPDWORD sizeW);
|
||||
STUB GetPrinterDataExA_stub;
|
||||
STUB GetPrinterDataExW_stub;
|
||||
STUB SetPrinterDataExA_stub;
|
||||
STUB SetPrinterDataExW_stub;
|
||||
FWDPROC AddJobW_fwd;
|
||||
FWDPROC AddMonitorW_fwd;
|
||||
FWDPROC AddPortW_fwd;
|
||||
FWDPROC AddPrinterDriverW_fwd;
|
||||
FWDPROC AddPrinterW_fwd;
|
||||
FWDPROC AddPrintProcessorW_fwd;
|
||||
FWDPROC AddPrintProvidorW_fwd;
|
||||
FWDPROC AdvancedDocumentPropertiesW_fwd;
|
||||
FWDPROC ConfigurePortW_fwd;
|
||||
FWDPROC DeleteMonitorW_fwd;
|
||||
FWDPROC DeletePortW_fwd;
|
||||
FWDPROC DeletePrinterDriverW_fwd;
|
||||
FWDPROC DeletePrintProcessorW_fwd;
|
||||
FWDPROC DeletePrintProvidorW_fwd;
|
||||
FWDPROC DeviceCapabilitiesW_fwd;
|
||||
FWDPROC DocumentPropertiesW_fwd;
|
||||
FWDPROC GetPrinterDriverDirectoryW_fwd;
|
||||
FWDPROC GetPrintProcessorDirectoryW_fwd;
|
||||
FWDPROC OpenPrinterW_fwd;
|
||||
FWDPROC ResetPrinterW_fwd;
|
||||
FWDPROC SetJobW_fwd;
|
||||
FWDPROC SetPrinterDataW_fwd;
|
||||
FWDPROC SetPrinterW_fwd;
|
||||
FWDPROC StartDocPrinterW_fwd;
|
||||
/*** AUTOGENERATED APILIST DECLARATIONS END ***/
|
||||
|
||||
#endif
|
||||
|
27
apilibs/kexbasen/winspool/_winspool_stubs.c
Executable file
27
apilibs/kexbasen/winspool/_winspool_stubs.c
Executable file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* KernelEx
|
||||
* Copyright (C) 2010, Tihiy
|
||||
*
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
* KernelEx is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* KernelEx is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
|
||||
UNIMPL_FUNC(GetPrinterDataExA, 7);
|
||||
UNIMPL_FUNC(GetPrinterDataExW, 7);
|
||||
UNIMPL_FUNC(SetPrinterDataExA, 6);
|
||||
UNIMPL_FUNC(SetPrinterDataExW, 6);
|
67
apilibs/kexbasen/winspool/uniwinspool.c
Executable file
67
apilibs/kexbasen/winspool/uniwinspool.c
Executable file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* KernelEx
|
||||
* Copyright (C) 2010, Tihiy
|
||||
*
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
* KernelEx is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* KernelEx is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include "unifwd.h"
|
||||
|
||||
//AddForm - not supported
|
||||
FORWARD_TO_UNICOWS(AddJobW);
|
||||
FORWARD_TO_UNICOWS(AddMonitorW);
|
||||
FORWARD_TO_UNICOWS(AddPortW);
|
||||
//AddPrinterConnection - not supported
|
||||
FORWARD_TO_UNICOWS(AddPrinterDriverW);
|
||||
FORWARD_TO_UNICOWS(AddPrinterW);
|
||||
FORWARD_TO_UNICOWS(AddPrintProcessorW);
|
||||
FORWARD_TO_UNICOWS(AddPrintProvidorW); //lol providor
|
||||
FORWARD_TO_UNICOWS(AdvancedDocumentPropertiesW);
|
||||
FORWARD_TO_UNICOWS(ConfigurePortW);
|
||||
//DeleteForm - not supported
|
||||
FORWARD_TO_UNICOWS(DeleteMonitorW);
|
||||
FORWARD_TO_UNICOWS(DeletePortW);
|
||||
//DeletePrinterConnection - not supported
|
||||
FORWARD_TO_UNICOWS(DeletePrinterDriverW);
|
||||
FORWARD_TO_UNICOWS(DeletePrintProcessorW);
|
||||
FORWARD_TO_UNICOWS(DeletePrintProvidorW);
|
||||
FORWARD_TO_UNICOWS(DeviceCapabilitiesW);
|
||||
FORWARD_TO_UNICOWS(DocumentPropertiesW);
|
||||
//EnumForms - not supported
|
||||
//EnumJobsW - not implemented
|
||||
//EnumMonitorsW - not implemented
|
||||
//EnumPortsW - not implemented
|
||||
//EnumPrinterDriversW - not implemented
|
||||
//EnumPrintersW - not implemented
|
||||
//EnumPrintProcessorDatatypesW - not implemented
|
||||
//EnumPrintProcessorsW - not implemented
|
||||
//GetForm - not supported
|
||||
//GetJobW - not implemented
|
||||
//GetPrinterDataW - not implemented
|
||||
FORWARD_TO_UNICOWS(GetPrinterDriverDirectoryW);
|
||||
//GetPrinterDriverW - not implemented
|
||||
//GetPrinterW - not implemented
|
||||
FORWARD_TO_UNICOWS(GetPrintProcessorDirectoryW);
|
||||
FORWARD_TO_UNICOWS(OpenPrinterW);
|
||||
FORWARD_TO_UNICOWS(ResetPrinterW);
|
||||
//SetForm - not supported
|
||||
FORWARD_TO_UNICOWS(SetJobW);
|
||||
//SetPrinterDataW - not implemented
|
||||
FORWARD_TO_UNICOWS(SetPrinterDataW); //lol lazy bastards
|
||||
FORWARD_TO_UNICOWS(SetPrinterW);
|
||||
FORWARD_TO_UNICOWS(StartDocPrinterW);
|
0
apilibs/kexbases/Advapi32/OpenSCManager_stub.c
Normal file → Executable file
0
apilibs/kexbases/Advapi32/OpenSCManager_stub.c
Normal file → Executable file
0
apilibs/kexbases/Advapi32/RegDisablePredefinedCache.c
Normal file → Executable file
0
apilibs/kexbases/Advapi32/RegDisablePredefinedCache.c
Normal file → Executable file
0
apilibs/kexbases/Advapi32/RegOpenCurrentUser.c
Normal file → Executable file
0
apilibs/kexbases/Advapi32/RegOpenCurrentUser.c
Normal file → Executable file
58
apilibs/kexbases/Advapi32/RtlGenRandom.c
Executable file
58
apilibs/kexbases/Advapi32/RtlGenRandom.c
Executable file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* KernelEx
|
||||
* Copyright (C) 2009 Tihiy
|
||||
* Copyright (C) 1999 George Marsaglia
|
||||
*
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
* KernelEx is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* KernelEx is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#define znew ((z=36969*(z&65535)+(z>>16))<<16)
|
||||
#define wnew ((w=18000*(w&65535)+(w>>16))&65535)
|
||||
#define MWC (znew+wnew)
|
||||
#define SHR3 (jsr=(jsr=(jsr=jsr^(jsr<<17))^(jsr>>13))^(jsr<<5))
|
||||
#define CONG (jcong=69069*jcong+1234567)
|
||||
#define KISS ((MWC^CONG)+SHR3)
|
||||
|
||||
/* Global static variables: */
|
||||
static unsigned long z=362436069, w=521288629, jsr=123456789, jcong=380116160;
|
||||
|
||||
/* MAKE_EXPORT SystemFunction036_new=SystemFunction036 */
|
||||
BOOL WINAPI SystemFunction036_new(PVOID pbBuffer, ULONG dwLen)
|
||||
{
|
||||
static BOOL bInit = FALSE;
|
||||
ULONG i;
|
||||
PUCHAR cBuffer = (PUCHAR) pbBuffer;
|
||||
|
||||
if (!pbBuffer || !dwLen)
|
||||
return FALSE;
|
||||
if (!bInit) //init once
|
||||
{
|
||||
z = GetTickCount();
|
||||
w = GetCurrentThreadId();
|
||||
jsr = GetCurrentProcessId();
|
||||
jcong = GetSysColor(COLOR_BACKGROUND);
|
||||
bInit = TRUE;
|
||||
}
|
||||
for (i=0;i<dwLen;i++)
|
||||
{
|
||||
*cBuffer = (UCHAR) KISS;
|
||||
cBuffer++;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
0
apilibs/kexbases/Advapi32/TraceMessage.c
Normal file → Executable file
0
apilibs/kexbases/Advapi32/TraceMessage.c
Normal file → Executable file
9
apilibs/kexbases/Advapi32/_advapi32_apilist.c
Normal file → Executable file
9
apilibs/kexbases/Advapi32/_advapi32_apilist.c
Normal file → Executable file
@ -55,8 +55,11 @@ static const apilib_named_api advapi32_named_apis[] =
|
||||
DECL_API("CryptSetProviderW", CryptSetProviderW_stub),
|
||||
DECL_API("CryptSignHashW", CryptSignHashW_stub),
|
||||
DECL_API("CryptVerifySignatureW", CryptVerifySignatureW_stub),
|
||||
DECL_API("DeleteAce", DeleteAce_new),
|
||||
DECL_API("DuplicateToken", DuplicateToken_new),
|
||||
DECL_API("DuplicateTokenEx", DuplicateTokenEx_new),
|
||||
DECL_API("EnumServicesStatusExA", EnumServicesStatusExA_stub),
|
||||
DECL_API("EnumServicesStatusExW", EnumServicesStatusExW_stub),
|
||||
DECL_API("EqualPrefixSid", EqualPrefixSid_new),
|
||||
DECL_API("EqualSid", EqualSid_new),
|
||||
DECL_API("FreeSid", FreeSid_new),
|
||||
@ -87,14 +90,16 @@ static const apilib_named_api advapi32_named_apis[] =
|
||||
DECL_API("LookupPrivilegeValueA", LookupPrivilegeValueA_new),
|
||||
DECL_API("LookupPrivilegeValueW", LookupPrivilegeValueW_new),
|
||||
DECL_API("MakeSelfRelativeSD", MakeSelfRelativeSD_new),
|
||||
DECL_API("NotifyBootConfigStatus", NotifyBootConfigStatus_new),
|
||||
DECL_API("NotifyBootConfigStatus", NotifyBootConfigStatus_stub),
|
||||
DECL_API("OpenProcessToken", OpenProcessToken_new),
|
||||
DECL_API("OpenSCManagerA", OpenSCManagerA_stub),
|
||||
DECL_API("OpenSCManagerW", OpenSCManagerW_stub),
|
||||
DECL_API("OpenThreadToken", OpenThreadToken_new),
|
||||
DECL_API("PrivilegeCheck", PrivilegeCheck_new),
|
||||
DECL_API("QueryServiceStatusEx", QueryServiceStatusEx_stub),
|
||||
DECL_API("QueryWindows31FilesMigration", QueryWindows31FilesMigration_stub),
|
||||
DECL_API("RegDisablePredefinedCache", RegDisablePredefinedCache_new),
|
||||
DECL_API("RegEnumValueW", RegEnumValueW_new),
|
||||
DECL_API("RegOpenCurrentUser", RegOpenCurrentUser_new),
|
||||
DECL_API("RegOverridePredefKey", RegOverridePredefKey_stub),
|
||||
DECL_API("RegQueryValueExW", RegQueryValueExW_new),
|
||||
@ -107,6 +112,8 @@ static const apilib_named_api advapi32_named_apis[] =
|
||||
DECL_API("SetSecurityDescriptorOwner", SetSecurityDescriptorOwner_new),
|
||||
DECL_API("SetSecurityDescriptorSacl", SetSecurityDescriptorSacl_new),
|
||||
DECL_API("SetThreadToken", SetThreadToken_new),
|
||||
DECL_API("SynchronizeWindows31FilesAndWindowsNTRegistry", SynchronizeWindows31FilesAndWindowsNTRegistry_stub),
|
||||
DECL_API("SystemFunction036", SystemFunction036_new),
|
||||
DECL_API("TraceMessage", TraceMessage_new),
|
||||
/*** AUTOGENERATED APILIST NAMED EXPORTS END ***/
|
||||
};
|
||||
|
9
apilibs/kexbases/Advapi32/_advapi32_apilist.h
Normal file → Executable file
9
apilibs/kexbases/Advapi32/_advapi32_apilist.h
Normal file → Executable file
@ -32,6 +32,7 @@ SC_HANDLE WINAPI OpenSCManagerA_stub(LPCSTR lpMachineName, LPCSTR lpDatabaseName
|
||||
SC_HANDLE WINAPI OpenSCManagerW_stub(LPCWSTR lpMachineName, LPCWSTR lpDatabaseName, DWORD dwDesiredAccess);
|
||||
BOOL WINAPI RegDisablePredefinedCache_new();
|
||||
LONG WINAPI RegOpenCurrentUser_new(REGSAM access, PHKEY retkey);
|
||||
BOOL WINAPI SystemFunction036_new(PVOID pbBuffer, ULONG dwLen);
|
||||
ULONG CDECL TraceMessage_new(ULONG64 LoggerHandle, ULONG MessageFlags, LPGUID MessageGuid, USHORT MessageNumber, ...);
|
||||
STUB CryptAcquireContextW_stub;
|
||||
STUB CryptEnumProvidersW_stub;
|
||||
@ -52,6 +53,11 @@ STUB ConvertStringSecurityDescriptorToSecurityDescriptorW_stub;
|
||||
STUB ConvertSecurityDescriptorToStringSecurityDescriptorA_stub;
|
||||
STUB ConvertSecurityDescriptorToStringSecurityDescriptorW_stub;
|
||||
STUB QueryServiceStatusEx_stub;
|
||||
STUB NotifyBootConfigStatus_stub;
|
||||
STUB QueryWindows31FilesMigration_stub;
|
||||
STUB SynchronizeWindows31FilesAndWindowsNTRegistry_stub;
|
||||
STUB EnumServicesStatusExA_stub;
|
||||
STUB EnumServicesStatusExW_stub;
|
||||
BOOL WINAPI OpenProcessToken_new(HANDLE ProcessHandle, DWORD DesiredAccess, HANDLE *TokenHandle);
|
||||
BOOL WINAPI OpenThreadToken_new(HANDLE ThreadHandle, DWORD DesiredAccess, BOOL OpenAsSelf, HANDLE *TokenHandle);
|
||||
BOOL WINAPI DuplicateTokenEx_new(HANDLE ExistingTokenHandle, DWORD dwDesiredAccess, LPSECURITY_ATTRIBUTES lpTokenAttributes, SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, TOKEN_TYPE TokenType, PHANDLE DuplicateTokenHandle);
|
||||
@ -94,7 +100,6 @@ BOOL WINAPI LookupAccountSidA_new(IN LPCSTR system, IN PSID sid, OUT LPSTR accou
|
||||
BOOL WINAPI LookupAccountSidW_new(IN LPCWSTR system, IN PSID sid, OUT LPWSTR account, IN OUT LPDWORD accountSize, OUT LPWSTR domain, IN OUT LPDWORD domainSize, OUT PSID_NAME_USE name_use);
|
||||
BOOL WINAPI SetFileSecurityA_new(LPCSTR lpFileName, SECURITY_INFORMATION RequestedInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor);
|
||||
BOOL WINAPI SetFileSecurityW_new(LPCWSTR lpFileName, SECURITY_INFORMATION RequestedInformation, PSECURITY_DESCRIPTOR pSecurityDescriptor);
|
||||
BOOL WINAPI NotifyBootConfigStatus_new(BOOL x1);
|
||||
BOOL WINAPI RevertToSelf_new(void);
|
||||
BOOL WINAPI ImpersonateSelf_new(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel);
|
||||
BOOL WINAPI AccessCheck_new(PSECURITY_DESCRIPTOR SecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess, PGENERIC_MAPPING GenericMapping, PPRIVILEGE_SET PrivilegeSet, LPDWORD PrivilegeSetLength, LPDWORD GrantedAccess, LPBOOL AccessStatus);
|
||||
@ -102,9 +107,11 @@ BOOL WINAPI SetKernelObjectSecurity_new (IN HANDLE Handle, IN SECURITY_INFORMATI
|
||||
BOOL WINAPI PrivilegeCheck_new(HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult);
|
||||
BOOL WINAPI AddAccessAllowedAce_new(IN OUT PACL pAcl, IN DWORD dwAceRevision, IN DWORD AccessMask, IN PSID pSid);
|
||||
BOOL WINAPI GetAce_new(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce);
|
||||
BOOL WINAPI DeleteAce_new(PACL pAcl, DWORD dwAceIndex);
|
||||
BOOL WINAPI CreateRestrictedToken_new(HANDLE baseToken, DWORD flags, DWORD nDisableSids, PSID_AND_ATTRIBUTES disableSids, DWORD nDeletePrivs, PLUID_AND_ATTRIBUTES deletePrivs, DWORD nRestrictSids, PSID_AND_ATTRIBUTES restrictSids, PHANDLE newToken);
|
||||
BOOL WINAPI CreateWellKnownSid_new(DWORD WellKnownSidType, PSID DomainSid, PSID pSid, DWORD* cbSid);
|
||||
LONG WINAPI RegQueryValueExW_new(HKEY hKey, LPCWSTR lpValueNameW, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData);
|
||||
LONG WINAPI RegEnumValueW_new(HKEY hKey, DWORD dwIndex, LPWSTR lpValueName, LPDWORD lpcValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData);
|
||||
/*** AUTOGENERATED APILIST DECLARATIONS END ***/
|
||||
|
||||
#endif
|
||||
|
7
apilibs/kexbases/Advapi32/_advapi32_stubs.c
Normal file → Executable file
7
apilibs/kexbases/Advapi32/_advapi32_stubs.c
Normal file → Executable file
@ -44,3 +44,10 @@ UNIMPL_FUNC(ConvertSecurityDescriptorToStringSecurityDescriptorA, 5);
|
||||
UNIMPL_FUNC(ConvertSecurityDescriptorToStringSecurityDescriptorW, 5);
|
||||
|
||||
UNIMPL_FUNC(QueryServiceStatusEx, 5);
|
||||
|
||||
UNIMPL_FUNC(NotifyBootConfigStatus, 1);
|
||||
UNIMPL_FUNC(QueryWindows31FilesMigration,2);
|
||||
UNIMPL_FUNC(SynchronizeWindows31FilesAndWindowsNTRegistry,4);
|
||||
|
||||
UNIMPL_FUNC(EnumServicesStatusExA, 10);
|
||||
UNIMPL_FUNC(EnumServicesStatusExW, 10);
|
||||
|
204
apilibs/kexbases/Advapi32/security.c
Normal file → Executable file
204
apilibs/kexbases/Advapi32/security.c
Normal file → Executable file
@ -3,6 +3,7 @@
|
||||
* Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
|
||||
* Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
|
||||
* Copyright 2007 Xeno86
|
||||
* Copyright 2009 Tihiy
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
@ -122,7 +123,6 @@ OpenThreadToken_new( HANDLE ThreadHandle, DWORD DesiredAccess,
|
||||
{
|
||||
FIXME("OpenThreadToken(0x%08x,0x08lx,0x%08x,%p): stub\n",
|
||||
ThreadHandle,DesiredAccess, OpenAsSelf, TokenHandle);
|
||||
if (OpenAsSelf) return FALSE; //shlwapi hack
|
||||
*(int*)TokenHandle = 0xcafe;
|
||||
return TRUE;
|
||||
}
|
||||
@ -454,7 +454,7 @@ CopySid_new( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid
|
||||
(nDestinationSidLength < GetLengthSid_new(pSourceSid)))
|
||||
return FALSE;
|
||||
|
||||
if (nDestinationSidLength < (((SID*)pSourceSid)->SubAuthorityCount*4+8))
|
||||
if (nDestinationSidLength < (((SID*)pSourceSid)->SubAuthorityCount*4u+8))
|
||||
return FALSE;
|
||||
|
||||
memmove(pDestinationSid, pSourceSid, ((SID*)pSourceSid)->SubAuthorityCount*4+8);
|
||||
@ -549,8 +549,11 @@ InitializeSid_new (
|
||||
int i;
|
||||
SID* pisid=(SID*)pSid;
|
||||
|
||||
if (nSubAuthorityCount >= SID_MAX_SUB_AUTHORITIES)
|
||||
if (!pSid || nSubAuthorityCount >= SID_MAX_SUB_AUTHORITIES)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pisid->Revision = SID_REVISION;
|
||||
pisid->SubAuthorityCount = nSubAuthorityCount;
|
||||
@ -897,7 +900,8 @@ SetSecurityDescriptorDacl_new (
|
||||
}
|
||||
|
||||
if (!daclpresent)
|
||||
{ lpsd->Control &= ~SE_DACL_PRESENT;
|
||||
{
|
||||
lpsd->Control &= ~SE_DACL_PRESENT;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -994,8 +998,86 @@ MakeSelfRelativeSD_new(
|
||||
IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
|
||||
IN OUT LPDWORD lpdwBufferLength)
|
||||
{
|
||||
FIXME("MakeSelfRelativeSD(%p,%p,%p(%lu))\n", pAbsoluteSecurityDescriptor,
|
||||
pSelfRelativeSecurityDescriptor, lpdwBufferLength,*lpdwBufferLength);
|
||||
DWORD offsetRel;
|
||||
ULONG length;
|
||||
SECURITY_DESCRIPTOR* pAbs = (SECURITY_DESCRIPTOR*)pAbsoluteSecurityDescriptor;
|
||||
SECURITY_DESCRIPTOR_RELATIVE* pRel = (SECURITY_DESCRIPTOR_RELATIVE*)pSelfRelativeSecurityDescriptor;
|
||||
|
||||
TRACE(" %p %p %p(%d)\n", pAbs, pRel, lpdwBufferLength,
|
||||
lpdwBufferLength ? *lpdwBufferLength: -1);
|
||||
|
||||
if (!lpdwBufferLength || !pAbs || !pRel)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
length = GetSecurityDescriptorLength_new(pAbs);
|
||||
if (*lpdwBufferLength < length)
|
||||
{
|
||||
*lpdwBufferLength = length;
|
||||
SetLastError(ERROR_INSUFFICIENT_BUFFER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (pAbs->Control & SE_SELF_RELATIVE)
|
||||
{
|
||||
memcpy(pRel, pAbs, length);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
pRel->Revision = pAbs->Revision;
|
||||
pRel->Sbz1 = pAbs->Sbz1;
|
||||
pRel->Control = pAbs->Control | SE_SELF_RELATIVE;
|
||||
|
||||
offsetRel = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
|
||||
if (pAbs->Owner)
|
||||
{
|
||||
pRel->Owner = offsetRel;
|
||||
length = GetLengthSid_new(pAbs->Owner);
|
||||
memcpy((LPBYTE)pRel + offsetRel, pAbs->Owner, length);
|
||||
offsetRel += length;
|
||||
}
|
||||
else
|
||||
{
|
||||
pRel->Owner = 0;
|
||||
}
|
||||
|
||||
if (pAbs->Group)
|
||||
{
|
||||
pRel->Group = offsetRel;
|
||||
length = GetLengthSid_new(pAbs->Group);
|
||||
memcpy((LPBYTE)pRel + offsetRel, pAbs->Group, length);
|
||||
offsetRel += length;
|
||||
}
|
||||
else
|
||||
{
|
||||
pRel->Group = 0;
|
||||
}
|
||||
|
||||
if (pAbs->Sacl)
|
||||
{
|
||||
pRel->Sacl = offsetRel;
|
||||
length = pAbs->Sacl->AclSize;
|
||||
memcpy((LPBYTE)pRel + offsetRel, pAbs->Sacl, length);
|
||||
offsetRel += length;
|
||||
}
|
||||
else
|
||||
{
|
||||
pRel->Sacl = 0;
|
||||
}
|
||||
|
||||
if (pAbs->Dacl)
|
||||
{
|
||||
pRel->Dacl = offsetRel;
|
||||
length = pAbs->Dacl->AclSize;
|
||||
memcpy((LPBYTE)pRel + offsetRel, pAbs->Dacl, length);
|
||||
}
|
||||
else
|
||||
{
|
||||
pRel->Dacl = 0;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -1053,8 +1135,8 @@ BOOL WINAPI InitializeAcl_new(PACL acl, DWORD size, DWORD rev)
|
||||
}
|
||||
|
||||
memset(acl,'\0',sizeof(ACL));
|
||||
acl->AclRevision = rev;
|
||||
acl->AclSize = size;
|
||||
acl->AclRevision = (UCHAR)rev;
|
||||
acl->AclSize = (USHORT)size;
|
||||
acl->AceCount = 0;
|
||||
return TRUE;
|
||||
}
|
||||
@ -1274,11 +1356,11 @@ LookupAccountSidW_new(
|
||||
name_use);
|
||||
|
||||
if (accountSize) *accountSize = lstrlenW(ac)+1;
|
||||
if (account && (*accountSize > lstrlenW(ac)))
|
||||
if (account && (*accountSize > (DWORD)lstrlenW(ac)))
|
||||
lstrcpyW(account, ac);
|
||||
|
||||
if (domainSize) *domainSize = lstrlenW(dm)+1;
|
||||
if (domain && (*domainSize > lstrlenW(dm)))
|
||||
if (domain && (*domainSize > (DWORD)lstrlenW(dm)))
|
||||
lstrcpyW(domain,dm);
|
||||
|
||||
if (name_use) *name_use = SidTypeUser;
|
||||
@ -1318,37 +1400,6 @@ SetFileSecurityW_new( LPCWSTR lpFileName,
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#if 0 /* unneeded ?? */
|
||||
/******************************************************************************
|
||||
* QueryWindows31FilesMigration [ADVAPI32.@]
|
||||
*
|
||||
* PARAMS
|
||||
* x1 []
|
||||
*/
|
||||
BOOL WINAPI
|
||||
QueryWindows31FilesMigration( DWORD x1 )
|
||||
{
|
||||
FIXME("(%ld):stub\n",x1);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
|
||||
*
|
||||
* PARAMS
|
||||
* x1 []
|
||||
* x2 []
|
||||
* x3 []
|
||||
* x4 []
|
||||
*/
|
||||
BOOL WINAPI
|
||||
SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
|
||||
DWORD x4 )
|
||||
{
|
||||
FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx):stub\n",x1,x2,x3,x4);
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0 /* LSA disabled */
|
||||
/******************************************************************************
|
||||
@ -1468,19 +1519,6 @@ LsaClose(IN LSA_HANDLE ObjectHandle)
|
||||
return 0xc0000000;
|
||||
}
|
||||
#endif
|
||||
/******************************************************************************
|
||||
* NotifyBootConfigStatus [ADVAPI32.@]
|
||||
*
|
||||
* PARAMS
|
||||
* x1 []
|
||||
*/
|
||||
/* MAKE_EXPORT NotifyBootConfigStatus_new=NotifyBootConfigStatus */
|
||||
BOOL WINAPI
|
||||
NotifyBootConfigStatus_new( BOOL x1 )
|
||||
{
|
||||
FIXME("NotifyBootConfigStatus(0x%08x):stub\n",x1);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* RevertToSelf [ADVAPI32.@]
|
||||
@ -1578,10 +1616,60 @@ BOOL WINAPI AddAccessAllowedAce_new(
|
||||
/* MAKE_EXPORT GetAce_new=GetAce */
|
||||
BOOL WINAPI GetAce_new(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
|
||||
{
|
||||
FIXME("GetAce(%p,%ld,%p),stub!\n",pAcl,dwAceIndex,pAce);
|
||||
PACE_HEADER ace;
|
||||
|
||||
TRACE("(%p,%d,%p)\n",pAcl,dwAceIndex,pAce);
|
||||
|
||||
if (!pAcl || !pAce || dwAceIndex >= pAcl->AceCount)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
ace = (PACE_HEADER)(pAcl + 1);
|
||||
for (;dwAceIndex;dwAceIndex--)
|
||||
ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
|
||||
|
||||
*pAce = ace;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* DeleteAce [ADVAPI32.@]
|
||||
*/
|
||||
/* MAKE_EXPORT DeleteAce_new=DeleteAce */
|
||||
BOOL WINAPI DeleteAce_new(PACL pAcl, DWORD dwAceIndex)
|
||||
{
|
||||
PACE_HEADER pAce;
|
||||
|
||||
if (!GetAce_new(pAcl,dwAceIndex,(LPVOID*)&pAce)) return FALSE;
|
||||
|
||||
PACE_HEADER pcAce;
|
||||
DWORD len = 0;
|
||||
|
||||
/* skip over the ACE we are deleting */
|
||||
pcAce = (PACE_HEADER)(((BYTE*)pAce)+pAce->AceSize);
|
||||
dwAceIndex++;
|
||||
|
||||
/* calculate the length of the rest */
|
||||
for (; dwAceIndex < pAcl->AceCount; dwAceIndex++)
|
||||
{
|
||||
len += pcAce->AceSize;
|
||||
pcAce = (PACE_HEADER)(((BYTE*)pcAce) + pcAce->AceSize);
|
||||
}
|
||||
|
||||
/* slide them all backwards */
|
||||
memmove(pAce, ((BYTE*)pAce)+pAce->AceSize, len);
|
||||
pAcl->AceCount--;
|
||||
|
||||
TRACE("pAcl=%p dwAceIndex=%d status=0x%08x\n", pAcl, dwAceIndex, status);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* CreateRestrictedToken [ADVAPI32.@]
|
||||
*/
|
||||
@ -1608,6 +1696,8 @@ BOOL WINAPI CreateRestrictedToken_new(
|
||||
/* MAKE_EXPORT CreateWellKnownSid_new=CreateWellKnownSid */
|
||||
BOOL WINAPI CreateWellKnownSid_new( DWORD WellKnownSidType, PSID DomainSid, PSID pSid, DWORD* cbSid)
|
||||
{
|
||||
FIXME("CreateWellKnownSid(%ld,%p,%p,%p,%p),stub!\n",WellKnownSidType,DomainSid,pSid,cbSid);
|
||||
return TRUE;
|
||||
FIXME("CreateWellKnownSid(%ld,%p,%p,%p,%p),mostly stub!\n",WellKnownSidType,DomainSid,pSid,cbSid);
|
||||
//BUGBUG what to do with cbSid? out sid size there?
|
||||
SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY};
|
||||
return InitializeSid_new(pSid, &localSidAuthority, 1);
|
||||
}
|
||||
|
144
apilibs/kexbases/Advapi32/uniadvapi32.c
Normal file → Executable file
144
apilibs/kexbases/Advapi32/uniadvapi32.c
Normal file → Executable file
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* KernelEx
|
||||
* Copyright (C) 2008, Xeno86
|
||||
* Copyright (C) 2008-2009, Xeno86
|
||||
* Copyright (C) 2009, Tihiy
|
||||
*
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
@ -31,21 +32,15 @@ LONG WINAPI RegQueryValueExW_new(HKEY hKey, LPCWSTR lpValueNameW, LPDWORD lpRese
|
||||
BYTE* ptr = stackbuf;
|
||||
BYTE* heapbuf = NULL;
|
||||
DWORD bufsize = sizeof(stackbuf);
|
||||
DWORD strsize;
|
||||
|
||||
if ((lpData && !lpcbData) || lpReserved) return ERROR_INVALID_PARAMETER;
|
||||
if (!lpData && lpcbData) *lpcbData = 0;
|
||||
|
||||
//try with stack buffer first
|
||||
if (lpValueNameW)
|
||||
{
|
||||
ALLOC_WtoA(lpValueName);
|
||||
ret = RegQueryValueExA(hKey, lpValueNameA, lpReserved, &type, ptr, &bufsize);
|
||||
if (lpType) *lpType = type;
|
||||
if (lpcbData && type != REG_SZ && bufsize > *lpcbData)
|
||||
{
|
||||
*lpcbData = bufsize;
|
||||
return ERROR_MORE_DATA;
|
||||
}
|
||||
|
||||
//retry with dynamic buffer
|
||||
if (ret == ERROR_MORE_DATA)
|
||||
{
|
||||
@ -56,58 +51,119 @@ LONG WINAPI RegQueryValueExW_new(HKEY hKey, LPCWSTR lpValueNameW, LPDWORD lpRese
|
||||
}
|
||||
ret = RegQueryValueExA(hKey, lpValueNameA, lpReserved, &type, ptr, &bufsize);
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == ERROR_SUCCESS && lpcbData) //copy data
|
||||
{
|
||||
switch(type) {
|
||||
case REG_SZ:
|
||||
case REG_EXPAND_SZ:
|
||||
case REG_MULTI_SZ:
|
||||
strsize = MultiByteToWideChar(CP_ACP,0,(LPSTR)ptr,bufsize,NULL,NULL)*sizeof(WCHAR);
|
||||
if (lpData)
|
||||
{
|
||||
if (*lpcbData<strsize)
|
||||
ret = ERROR_MORE_DATA;
|
||||
else
|
||||
{
|
||||
ret = RegQueryValueExA(hKey, 0, lpReserved, &type, ptr, &bufsize);
|
||||
if (lpType) *lpType = type;
|
||||
if (lpcbData && type != REG_SZ && bufsize > *lpcbData)
|
||||
{
|
||||
*lpcbData = bufsize;
|
||||
return ERROR_MORE_DATA;
|
||||
MultiByteToWideChar(CP_ACP,0,(LPSTR)ptr,bufsize,(LPWSTR)lpData,*lpcbData/sizeof(WCHAR));
|
||||
}
|
||||
//retry with dynamic buffer
|
||||
if (ret == ERROR_MORE_DATA)
|
||||
*lpcbData = strsize;
|
||||
break;
|
||||
default:
|
||||
if (lpData)
|
||||
{
|
||||
if (*lpcbData<bufsize)
|
||||
ret = ERROR_MORE_DATA;
|
||||
else
|
||||
memcpy(lpData, ptr, bufsize);
|
||||
}
|
||||
*lpcbData = bufsize;
|
||||
}
|
||||
}
|
||||
|
||||
if (heapbuf) HeapFree(GetProcessHeap(), 0, heapbuf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//MAKE_EXPORT RegEnumValueW_new=RegEnumValueW
|
||||
LONG WINAPI RegEnumValueW_new(
|
||||
HKEY hKey, // handle to key to query
|
||||
DWORD dwIndex, // index of value to query
|
||||
LPWSTR lpValueName, // value buffer
|
||||
LPDWORD lpcValueName, // size of value buffer
|
||||
LPDWORD lpReserved, // reserved
|
||||
LPDWORD lpType, // type buffer
|
||||
LPBYTE lpData, // data buffer
|
||||
LPDWORD lpcbData // size of data buffer
|
||||
)
|
||||
{
|
||||
LONG ret;
|
||||
DWORD type;
|
||||
CHAR valnamebuf[256];
|
||||
DWORD valsize = sizeof(valnamebuf);
|
||||
BYTE stackbuf[256];
|
||||
DWORD bufsize = sizeof(stackbuf);
|
||||
BYTE* ptr = stackbuf;
|
||||
BYTE* heapbuf = NULL;
|
||||
DWORD strsize;
|
||||
|
||||
if ((lpData && !lpcbData) || !lpValueName || !lpcValueName) return ERROR_INVALID_PARAMETER;
|
||||
|
||||
ret = RegEnumValueA(hKey, dwIndex, valnamebuf, &valsize, lpReserved, &type, ptr, &bufsize);
|
||||
if (lpType) *lpType = type;
|
||||
|
||||
if (ret == ERROR_MORE_DATA) //retry with heap buffer
|
||||
{
|
||||
ptr = heapbuf = (BYTE*) HeapAlloc(GetProcessHeap(), 0, bufsize);
|
||||
if (!heapbuf)
|
||||
{
|
||||
return ERROR_NOT_ENOUGH_MEMORY;
|
||||
}
|
||||
ret = RegQueryValueExA(hKey, 0, lpReserved, &type, ptr, &bufsize);
|
||||
ret = RegEnumValueA(hKey, dwIndex, valnamebuf, &valsize, lpReserved, &type, ptr, &bufsize);
|
||||
}
|
||||
}
|
||||
if (ret != ERROR_SUCCESS) goto _end;
|
||||
|
||||
if (type == REG_SZ)
|
||||
//check if value name buffer is big enough
|
||||
//note, it has to be with null while we have size without
|
||||
//also note, if buffer for value name is not long enough
|
||||
//RegEnumValue will not set *lpcValueName to right size
|
||||
//(9x also erroneously does (*lpcValueName)--;)
|
||||
|
||||
valsize++;
|
||||
if (ret == ERROR_SUCCESS && *lpcValueName<valsize) ret = ERROR_MORE_DATA;
|
||||
|
||||
if (ret == ERROR_SUCCESS && lpcbData) //copy data
|
||||
{
|
||||
if (lpcbData)
|
||||
switch(type) {
|
||||
case REG_SZ:
|
||||
case REG_EXPAND_SZ:
|
||||
case REG_MULTI_SZ:
|
||||
strsize = MultiByteToWideChar(CP_ACP,0,(LPSTR)ptr,bufsize,NULL,NULL)*sizeof(WCHAR);
|
||||
if (lpData)
|
||||
{
|
||||
DWORD gle = GetLastError();
|
||||
int written = MultiByteToWideChar(CP_ACP, 0, (LPSTR) ptr, -1,
|
||||
(LPWSTR)lpData, lpData ? (*lpcbData >> 1) : 0);
|
||||
if (!written)
|
||||
{
|
||||
ret = GetLastError();
|
||||
if (ret == ERROR_INSUFFICIENT_BUFFER)
|
||||
{
|
||||
*lpcbData = MultiByteToWideChar(CP_ACP, 0, (LPSTR) ptr,
|
||||
-1, NULL, 0) << 1;
|
||||
if (*lpcbData<strsize)
|
||||
ret = ERROR_MORE_DATA;
|
||||
}
|
||||
SetLastError(gle);
|
||||
goto _end;
|
||||
}
|
||||
*lpcbData = written << 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
MultiByteToWideChar(CP_ACP,0,(LPSTR)ptr,bufsize,(LPWSTR)lpData,*lpcbData/sizeof(WCHAR));
|
||||
}
|
||||
*lpcbData = strsize;
|
||||
break;
|
||||
default:
|
||||
if (lpData)
|
||||
{
|
||||
if (lpData) memcpy(lpData, ptr, bufsize);
|
||||
if (lpcbData) *lpcbData = bufsize;
|
||||
if (*lpcbData<bufsize)
|
||||
ret = ERROR_MORE_DATA;
|
||||
else
|
||||
memcpy(lpData, ptr, bufsize);
|
||||
}
|
||||
*lpcbData = bufsize;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == ERROR_SUCCESS) //copy valname
|
||||
{
|
||||
*lpcValueName = MultiByteToWideChar(CP_ACP,0,valnamebuf,valsize,lpValueName,*lpcValueName);
|
||||
(*lpcValueName)--;
|
||||
}
|
||||
|
||||
_end:
|
||||
if (heapbuf) HeapFree(GetProcessHeap(), 0, heapbuf);
|
||||
return ret;
|
||||
}
|
||||
|
0
apilibs/kexbases/Gdi32/FontResourceExA.c
Normal file → Executable file
0
apilibs/kexbases/Gdi32/FontResourceExA.c
Normal file → Executable file
250
apilibs/kexbases/Gdi32/GdiObjects.c
Executable file
250
apilibs/kexbases/Gdi32/GdiObjects.c
Executable file
@ -0,0 +1,250 @@
|
||||
/*
|
||||
* KernelEx
|
||||
*
|
||||
* Copyright (C) 2009, Tihiy
|
||||
*
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
* KernelEx is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* KernelEx is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include "GdiObjects.h"
|
||||
#include "k32ord.h"
|
||||
#include "kexcoresdk.h"
|
||||
|
||||
static BOOL blockkexgdiobj;
|
||||
static WORD g_GDILH_addr;
|
||||
static DWORD g_GdiBase;
|
||||
|
||||
#define REBASEGDI(x) ((PVOID)( g_GdiBase + LOWORD((DWORD)(x)) ))
|
||||
#define REBASEGDIHIGH(x) ( g_GdiBase + (DWORD)(x) )
|
||||
|
||||
#define GDIHEAP32BASE 0x10000
|
||||
#define GDIHEAP32TOP 0x20000
|
||||
|
||||
BOOL InitGDIObjects(void)
|
||||
{
|
||||
g_GdiBase = MapSL( LoadLibrary16("gdi") << 16 );
|
||||
g_GDILH_addr = ((PINSTANCE16)g_GdiBase)->pLocalHeap;
|
||||
blockkexgdiobj = (BOOL)GetProcAddress(GetModuleHandle("rp10.dll"),"blockkexgdiobj");
|
||||
return (BOOL)g_GdiBase;
|
||||
}
|
||||
|
||||
PGDIOBJ16 GetGDIObjectPtr( HGDIOBJ hgdiobj )
|
||||
{
|
||||
WORD wHandle = (WORD)hgdiobj;
|
||||
if ( wHandle & 1 ) return NULL; //all gdi handles end in b10 or b00, not b01
|
||||
if ( wHandle & 3 ) //64K heap
|
||||
{
|
||||
PLHENTRY entry = (PLHENTRY)REBASEGDI( wHandle );
|
||||
if ( wHandle <= g_GDILH_addr || entry->bFlags == LHE_FREEHANDLE || entry->wBlock <= g_GDILH_addr )
|
||||
return NULL; //deleted or invalid handle
|
||||
if ( entry->bFlags & LHE_DISCARDED ) //discarded DC
|
||||
{
|
||||
if ( entry->wBlock & 3 ) return NULL; //they have to divide by 4
|
||||
return GetGDIObjectPtr( (HGDIOBJ)entry->wBlock ); //recurse
|
||||
}
|
||||
else
|
||||
{
|
||||
return (PGDIOBJ16)REBASEGDI(entry->wBlock);
|
||||
}
|
||||
}
|
||||
else //high heap
|
||||
__try
|
||||
{
|
||||
if ( wHandle < 0x80 ) return NULL; //high heap handles start with 0x80
|
||||
if ( wHandle > *(WORD*)REBASEGDIHIGH( GDIHEAP32BASE + 0x70 ) ) return NULL; //max hadle value there
|
||||
DWORD* high = (DWORD*)REBASEGDIHIGH( GDIHEAP32BASE + wHandle );
|
||||
if ( *high < GDIHEAP32TOP ) return NULL; //points to invalid handle memory
|
||||
PGDIOBJ16 ret = (PGDIOBJ16)REBASEGDIHIGH( *high );
|
||||
if ( ret->wType == 0 ) return NULL; //points to invalid object memory
|
||||
return ret;
|
||||
}
|
||||
__except (EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static DWORD SwitchGDIObjectType( PGDIOBJ16 obj )
|
||||
{
|
||||
__try
|
||||
{
|
||||
switch ( obj->wType & GDI_TYPEMASK )
|
||||
{
|
||||
case GDI_TYPE_PEN:
|
||||
return OBJ_PEN;
|
||||
case GDI_TYPE_BRUSH:
|
||||
return OBJ_BRUSH;
|
||||
case GDI_TYPE_FONT:
|
||||
return OBJ_FONT;
|
||||
case GDI_TYPE_PAL:
|
||||
return OBJ_PAL;
|
||||
case GDI_TYPE_BITMAP:
|
||||
return OBJ_BITMAP;
|
||||
case GDI_TYPE_REGION:
|
||||
return OBJ_REGION;
|
||||
case GDI_TYPE_DC:
|
||||
{
|
||||
PDCOBJ dcobj = (PDCOBJ)obj;
|
||||
if ( dcobj->enhmetadc ) return OBJ_ENHMETADC;
|
||||
if ( dcobj->dcFlags & 1 ) return OBJ_MEMDC;
|
||||
//fall down
|
||||
}
|
||||
case GDI_TYPE_DCX:
|
||||
case GDI_TYPE_DCY:
|
||||
return OBJ_DC;
|
||||
case GDI_TYPE_METADC:
|
||||
return OBJ_METADC;
|
||||
case GDI_TYPE_ENHMETA:
|
||||
return OBJ_ENHMETAFILE;
|
||||
}
|
||||
}
|
||||
__except(EXCEPTION_EXECUTE_HANDLER)
|
||||
{
|
||||
//too bad
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* MAKE_EXPORT GetObjectType_fix=GetObjectType */
|
||||
DWORD WINAPI GetObjectType_fix( HGDIOBJ hgdiobj )
|
||||
{
|
||||
if (blockkexgdiobj) return GetObjectType(hgdiobj);
|
||||
//GetObjectType is rewritten in order to boost it's correctness and speed:
|
||||
//constantly throwing page/segfaults is very bad on virtual machines.
|
||||
PGDIOBJ16 obj = GetGDIObjectPtr( hgdiobj );
|
||||
DWORD result = 0;
|
||||
if ( obj )
|
||||
{
|
||||
GrabWin16Lock();
|
||||
result = SwitchGDIObjectType( obj );
|
||||
ReleaseWin16Lock();
|
||||
}
|
||||
else //still, can be metafile selector
|
||||
{
|
||||
WORD wHandle = (WORD)hgdiobj;
|
||||
if ( (wHandle & 6) == 6 ) //test for ldt selector
|
||||
{
|
||||
LDT_ENTRY selector;
|
||||
GetThreadSelectorEntry( GetCurrentThread(), wHandle, &selector );
|
||||
if ( selector.HighWord.Bits.Type == 3 )
|
||||
result = GetObjectType(hgdiobj); //resort to gdi32
|
||||
}
|
||||
}
|
||||
if ( !result ) SetLastError( ERROR_INVALID_HANDLE );
|
||||
return result;
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT DeleteObject_fix=DeleteObject */
|
||||
BOOL WINAPI DeleteObject_fix( HGDIOBJ hObject )
|
||||
{
|
||||
if (blockkexgdiobj) return DeleteObject(hObject);
|
||||
PGDIOBJ16 obj = GetGDIObjectPtr( hObject );
|
||||
if ( !obj || !SwitchGDIObjectType(obj) ) return FALSE;
|
||||
DWORD violated = 0;
|
||||
if ( obj->wOwner ) //not system objects
|
||||
{
|
||||
if (obj->wType == GDI_TYPE_FONT && ((PFONTOBJ16)obj)->wSelCount >= SEL_FONT_ONCE )
|
||||
{
|
||||
DBGPRINTF(("somebody is trying to delete selected font %p\n",hObject));
|
||||
violated = GDI_TYPE_FONT;
|
||||
}
|
||||
if (obj->wType == GDI_TYPE_BITMAP && ((PBITMAPOBJ16)obj)->wSelCount == SEL_BITMAP_ONCE )
|
||||
{
|
||||
DBGPRINTF(("somebody is trying to delete selected bitmap %p\n",hObject));
|
||||
violated = GDI_TYPE_BITMAP;
|
||||
}
|
||||
}
|
||||
BOOL ret = DeleteObject( hObject );
|
||||
if ( violated == GDI_TYPE_FONT )
|
||||
((PFONTOBJ16)obj)->wSelCount |= SEL_FONT_DEL;
|
||||
else if ( violated == GDI_TYPE_BITMAP )
|
||||
((PBITMAPOBJ16)obj)->wSelCount |= SEL_BITMAP_DEL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT SelectObject_fix=SelectObject */
|
||||
HGDIOBJ WINAPI SelectObject_fix( HDC hdc, HGDIOBJ hgdiobj )
|
||||
{
|
||||
if (blockkexgdiobj) return SelectObject(hdc,hgdiobj);
|
||||
//9x should do this
|
||||
if ( !hdc ) SetLastError(ERROR_INVALID_HANDLE);
|
||||
if ( !hdc || !hgdiobj ) return NULL;
|
||||
HGDIOBJ ret;
|
||||
ret = SelectObject( hdc, hgdiobj );
|
||||
PGDIOBJ16 obj = GetGDIObjectPtr( ret );
|
||||
if ( obj && obj->wOwner )
|
||||
{
|
||||
if ( obj->wType == GDI_TYPE_FONT && ((PFONTOBJ16)obj)->wSelCount == SEL_FONT_DEL )
|
||||
{
|
||||
DBGPRINTF(("deleting font %p on unselecting\n",ret));
|
||||
DeleteObject(ret);
|
||||
}
|
||||
if ( obj->wType == GDI_TYPE_BITMAP && ((PBITMAPOBJ16)obj)->wSelCount == SEL_BITMAP_DEL )
|
||||
{
|
||||
((PBITMAPOBJ16)obj)->wSelCount = 0;
|
||||
DBGPRINTF(("deleting bitmap %p on unselecting\n",ret));
|
||||
DeleteObject(ret);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT DeleteDC_fix=DeleteDC */
|
||||
BOOL WINAPI DeleteDC_fix( HDC hdc )
|
||||
{
|
||||
if (blockkexgdiobj) return DeleteDC(hdc);
|
||||
BOOL ret;
|
||||
PGDIOBJ16 obj = GetGDIObjectPtr( hdc );
|
||||
if ( !obj || !SwitchGDIObjectType(obj) ) return FALSE;
|
||||
HGDIOBJ fnt = GetCurrentObject(hdc,OBJ_FONT);
|
||||
HGDIOBJ bmp = GetCurrentObject(hdc,OBJ_BITMAP);
|
||||
ret = DeleteDC(hdc);
|
||||
if (ret)
|
||||
{
|
||||
PFONTOBJ16 fntobj = (PFONTOBJ16)GetGDIObjectPtr(fnt);
|
||||
PBITMAPOBJ16 bitmapobj = (PBITMAPOBJ16)GetGDIObjectPtr(bmp);
|
||||
if (fntobj && fntobj->wOwner && fntobj->wType == GDI_TYPE_FONT && fntobj->wSelCount == SEL_FONT_DEL)
|
||||
{
|
||||
DBGPRINTF(("deleting font %p on dc cleanup\n",fnt));
|
||||
DeleteObject(fnt);
|
||||
}
|
||||
if (bitmapobj && bitmapobj->header.wOwner && bitmapobj->header.wType == GDI_TYPE_BITMAP && bitmapobj->wSelCount == SEL_BITMAP_DEL)
|
||||
{
|
||||
bitmapobj->wSelCount = 0;
|
||||
DBGPRINTF(("deleting bitmap %p on dc cleanup\n",bmp));
|
||||
DeleteObject(bmp);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT CreateDIBSection_fix=CreateDIBSection */
|
||||
HBITMAP WINAPI CreateDIBSection_fix(
|
||||
HDC hdc, // handle to DC
|
||||
BITMAPINFO *pbmi, // bitmap data
|
||||
UINT iUsage, // data type indicator
|
||||
VOID **ppvBits, // bit values
|
||||
HANDLE hSection, // handle to file mapping object
|
||||
DWORD dwOffset // offset to bitmap bit values
|
||||
)
|
||||
{
|
||||
if (pbmi && pbmi->bmiHeader.biSize == sizeof(BITMAPINFO)) //9x does not forgive
|
||||
pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); //9x does not forget
|
||||
return CreateDIBSection(hdc,pbmi,iUsage,ppvBits,hSection,dwOffset);
|
||||
}
|
140
apilibs/kexbases/Gdi32/GdiObjects.h
Executable file
140
apilibs/kexbases/Gdi32/GdiObjects.h
Executable file
@ -0,0 +1,140 @@
|
||||
/*
|
||||
* KernelEx
|
||||
*
|
||||
* Copyright (C) 2009, Tihiy
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
* KernelEx is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* KernelEx is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __GDI9X_H
|
||||
#define __GDI9X_H
|
||||
|
||||
//those are in thunilay
|
||||
void GrabWin16Lock();
|
||||
void ReleaseWin16Lock();
|
||||
|
||||
#define LHE_DISCARDED 0x40
|
||||
#define LHE_MUTATED 0x80
|
||||
#define LHE_FREEHANDLE 0xFF
|
||||
|
||||
#define GDI_TYPEMASK 0x5FFF
|
||||
#define GDI_TYPE_PEN 0x4F47
|
||||
#define GDI_TYPE_BRUSH 0x4F48
|
||||
#define GDI_TYPE_FONT 0x4F49
|
||||
#define GDI_TYPE_PAL 0x4F4A
|
||||
#define GDI_TYPE_BITMAP 0x4F4B
|
||||
#define GDI_TYPE_REGION 0x4F4C
|
||||
#define GDI_TYPE_DC 0x4F4D
|
||||
#define GDI_TYPE_DCX 0x4F4E
|
||||
#define GDI_TYPE_DCY 0x4F4F
|
||||
#define GDI_TYPE_METADC 0x4F51
|
||||
#define GDI_TYPE_ENHMETA 0x4F52
|
||||
|
||||
#define SEL_FONT_ONCE 0x4
|
||||
#define SEL_FONT_DEL 0x2
|
||||
#define SEL_BITMAP_ONCE 0x01
|
||||
#define SEL_BITMAP_DEL 0x10
|
||||
|
||||
#define ResetMapMode( hdc ) SetMapMode( hdc, GetMapMode(hdc) )
|
||||
|
||||
#pragma pack(push,1)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WORD bDoesntExist;
|
||||
DWORD dwOldSSSP;
|
||||
WORD pLocalHeap;
|
||||
WORD pAtomTable;
|
||||
WORD pStackTop;
|
||||
WORD pStackMin;
|
||||
WORD pStackBottom;
|
||||
} INSTANCE16, *PINSTANCE16;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WORD wBlock;
|
||||
BYTE bFlags;
|
||||
BYTE bLocks;
|
||||
} LHENTRY, *PLHENTRY;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WORD wZero; //+0
|
||||
WORD wType; //+2
|
||||
DWORD dwNumber; //+4
|
||||
DWORD dwSpecific; //+8
|
||||
WORD wOwner; //+C
|
||||
} GDIOBJ16, *PGDIOBJ16;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GDIOBJ16 header;
|
||||
WORD wGlobalBitmap; //+14
|
||||
WORD wSelCount; //+16
|
||||
WORD wHDC; //+18
|
||||
WORD wGlobalBitmapInfo; //+20
|
||||
DWORD dwReservedShit; //+22
|
||||
WORD wBitmapStuff; //+26
|
||||
WORD wDeviceStuff; //+28
|
||||
WORD wBitmapType; //+30
|
||||
WORD wLogColorSpace; //+32
|
||||
} BITMAPOBJ16, *PBITMAPOBJ16;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WORD wZero; //+0
|
||||
WORD wType; //+2
|
||||
DWORD dwStuff; //+4
|
||||
WORD wReserved; //+8 (not used?)
|
||||
WORD wSelCount; //+A
|
||||
WORD wOwner; //+C
|
||||
} FONTOBJ16, *PFONTOBJ16;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WORD wZero; //+0
|
||||
WORD wType; //+2
|
||||
DWORD dwNumber; //+4
|
||||
DWORD dwBrushStuff; //+8
|
||||
WORD wOwner; //+C
|
||||
DWORD dcFlags; //+E
|
||||
DWORD stuff[3]; //+12
|
||||
WORD wBitmapHandle; //+1E
|
||||
DWORD stuff2[4]; //+20
|
||||
WORD dummy2; //+30
|
||||
WORD wGlobalBitmapSelector; //+32
|
||||
WORD dummy; //+34
|
||||
WORD wGlobalBitmap; //+36
|
||||
BYTE skip1[0x4C]; //+38
|
||||
WORD WindowExtX; //+84
|
||||
WORD WindowExtY; //+86
|
||||
BYTE filler2[4]; //+88
|
||||
WORD ViewportExtX; //+8C
|
||||
WORD ViewportExtY; //+8E
|
||||
BYTE filler3[4]; //+90
|
||||
WORD mapmode; //+94
|
||||
BYTE filler4[0x68]; //+96
|
||||
DWORD lockFlags; //+FE
|
||||
DWORD skip2; //+102
|
||||
WORD enhmetadc; //+106
|
||||
} DCOBJ, *PDCOBJ;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
PGDIOBJ16 GetGDIObjectPtr( HGDIOBJ hgdiobj );
|
||||
#define GetDCObj(x) (PDCOBJ)GetGDIObjectPtr(x)
|
||||
|
||||
#endif
|
0
apilibs/kexbases/Gdi32/GetGlyphOutlineA_fix.c
Normal file → Executable file
0
apilibs/kexbases/Gdi32/GetGlyphOutlineA_fix.c
Normal file → Executable file
31
apilibs/kexbases/Gdi32/TextOut.c
Normal file → Executable file
31
apilibs/kexbases/Gdi32/TextOut.c
Normal file → Executable file
@ -28,8 +28,7 @@
|
||||
#include <windows.h>
|
||||
#include <malloc.h>
|
||||
|
||||
#include "gdi9x.h"
|
||||
#include "k32ord.h"
|
||||
#include "GdiObjects.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#ifdef __cplusplus
|
||||
@ -42,11 +41,6 @@ __declspec(selectany) int _fltused=1;
|
||||
#define ETO_PDY 0x2000
|
||||
#endif
|
||||
|
||||
static DWORD g_GdiBase;
|
||||
#define REBASEGDI(x) ( g_GdiBase + (DWORD)(x) )
|
||||
|
||||
|
||||
|
||||
/* MAKE_EXPORT GetFontUnicodeRanges_new=GetFontUnicodeRanges */
|
||||
DWORD WINAPI GetFontUnicodeRanges_new(
|
||||
HDC hdc,
|
||||
@ -93,29 +87,6 @@ int WINAPI GetRandomRgn_NT(
|
||||
return result;
|
||||
}
|
||||
|
||||
PDCOBJ GetDCObj( HDC hDC )
|
||||
{
|
||||
PDCOBJ retobj;
|
||||
PLHENTRY entry;
|
||||
if (!hDC) return NULL;
|
||||
if (!g_GdiBase) g_GdiBase = MapSL( LoadLibrary16("gdi") << 16 );
|
||||
entry = (PLHENTRY)REBASEGDI(LOWORD(hDC));
|
||||
if ( !entry->wBlock || entry->bFlags == LHE_FREEHANDLE ) return NULL;
|
||||
if ( entry->bFlags & LHE_DISCARDED )
|
||||
{
|
||||
if ( entry->wBlock & 3 ) return NULL; //32-bit handles have to divide by 4
|
||||
DWORD* highDC = (DWORD*)REBASEGDI( 0x10000 + entry->wBlock );
|
||||
if ( IsBadReadPtr(highDC,sizeof(DWORD)) ) return NULL; //oops dead handle
|
||||
retobj = (PDCOBJ)REBASEGDI(*highDC);
|
||||
if ( IsBadReadPtr(retobj,sizeof(DCOBJ)) ) return NULL; //oops?!
|
||||
}
|
||||
else
|
||||
retobj = (PDCOBJ)REBASEGDI(entry->wBlock);
|
||||
WORD checktype = (retobj->wType & GDI_OBJTYPE_MASK);
|
||||
if ( checktype != GDI_OBJTYPE_DC && checktype != GDI_OBJTYPE_DC_NO ) return NULL;
|
||||
return retobj;
|
||||
}
|
||||
|
||||
void floattofrac( float f, int* m, int* d)
|
||||
{
|
||||
float absf = f > 0 ? f : -f;
|
||||
|
15
apilibs/kexbases/Gdi32/_gdi32_apilist.c
Normal file → Executable file
15
apilibs/kexbases/Gdi32/_gdi32_apilist.c
Normal file → Executable file
@ -20,12 +20,13 @@
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "kexcoresdk.h"
|
||||
#include "_gdi32_apilist.h"
|
||||
|
||||
BOOL InitGDIObjects(void);
|
||||
|
||||
BOOL init_gdi32()
|
||||
{
|
||||
return TRUE;
|
||||
return InitGDIObjects();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -40,14 +41,23 @@ static const apilib_named_api gdi32_named_apis[] =
|
||||
DECL_API("AddFontResourceExA", AddFontResourceExA_new),
|
||||
DECL_API("AddFontResourceExW", AddFontResourceExW_new),
|
||||
DECL_API("AddFontResourceW", AddFontResourceW_new),
|
||||
DECL_API("CreateDIBSection", CreateDIBSection_fix),
|
||||
DECL_API("DeleteDC", DeleteDC_fix),
|
||||
DECL_API("DeleteObject", DeleteObject_fix),
|
||||
DECL_API("EnumFontFamiliesExA", EnumFontFamiliesExA_new),
|
||||
DECL_API("EnumFontFamiliesExW", EnumFontFamiliesExW_new),
|
||||
DECL_API("EnumFontFamiliesW", EnumFontFamiliesW_new),
|
||||
DECL_API("ExtCreatePen", ExtCreatePen_fix),
|
||||
DECL_API("ExtTextOutA", ExtTextOutA_new),
|
||||
DECL_API("ExtTextOutW", ExtTextOutW_new),
|
||||
DECL_API("GetCharWidth32A", GetCharWidthA),
|
||||
DECL_API("GetCharWidth32W", GetCharWidthW),
|
||||
DECL_API("GetDCBrushColor", GetDCBrushColor_stub),
|
||||
DECL_API("GetDCPenColor", GetDCPenColor_stub),
|
||||
DECL_API("GetFontUnicodeRanges", GetFontUnicodeRanges_new),
|
||||
DECL_API("GetGlyphOutlineA", GetGlyphOutlineA_fix),
|
||||
DECL_API("GetObjectType", GetObjectType_fix),
|
||||
DECL_API("GetObjectW", GetObjectW_new),
|
||||
DECL_API("GetRandomRgn", GetRandomRgn_NT),
|
||||
DECL_API("GetTextMetricsA", GetTextMetricsA_NT),
|
||||
DECL_API("GetWorldTransform", GetWorldTransform_NT),
|
||||
@ -58,6 +68,7 @@ static const apilib_named_api gdi32_named_apis[] =
|
||||
DECL_API("RemoveFontResourceExA", RemoveFontResourceExA_new),
|
||||
DECL_API("RemoveFontResourceExW", RemoveFontResourceExW_new),
|
||||
DECL_API("RemoveFontResourceW", RemoveFontResourceW_new),
|
||||
DECL_API("SelectObject", SelectObject_fix),
|
||||
DECL_API("SetDCBrushColor", SetDCBrushColor_stub),
|
||||
DECL_API("SetDCPenColor", SetDCPenColor_stub),
|
||||
DECL_API("SetGraphicsMode", SetGraphicsMode_NT),
|
||||
|
10
apilibs/kexbases/Gdi32/_gdi32_apilist.h
Normal file → Executable file
10
apilibs/kexbases/Gdi32/_gdi32_apilist.h
Normal file → Executable file
@ -30,6 +30,11 @@ extern const apilib_api_table apitable_gdi32;
|
||||
/*** AUTOGENERATED APILIST DECLARATIONS BEGIN ***/
|
||||
INT WINAPI AddFontResourceExA_new(LPCSTR str, DWORD fl, PVOID pdv);
|
||||
BOOL WINAPI RemoveFontResourceExA_new(LPCSTR str, DWORD fl, PVOID pdv);
|
||||
DWORD WINAPI GetObjectType_fix(HGDIOBJ hgdiobj);
|
||||
BOOL WINAPI DeleteObject_fix(HGDIOBJ hObject);
|
||||
HGDIOBJ WINAPI SelectObject_fix(HDC hdc, HGDIOBJ hgdiobj);
|
||||
BOOL WINAPI DeleteDC_fix(HDC hdc);
|
||||
HBITMAP WINAPI CreateDIBSection_fix(HDC hdc, BITMAPINFO *pbmi, UINT iUsage, VOID **ppvBits, HANDLE hSection, DWORD dwOffset);
|
||||
DWORD WINAPI GetGlyphOutlineA_fix(HDC hdc, UINT uChar, UINT uFormat, LPGLYPHMETRICS lpgm, DWORD cbBuffer, LPVOID lpvBuffer, CONST MAT2 *lpmat2);
|
||||
DWORD WINAPI GetFontUnicodeRanges_new(HDC hdc, LPGLYPHSET lpgs);
|
||||
int WINAPI SetGraphicsMode_NT(HDC hdc, int iMode);
|
||||
@ -46,14 +51,19 @@ BOOL WINAPI PolyTextOutA_new(HDC hdc, const POLYTEXTA *pptxt, INT cStrings);
|
||||
BOOL WINAPI PolyTextOutW_new(HDC hdc, const POLYTEXTW *pptxt, INT cStrings);
|
||||
STUB SetDCBrushColor_stub;
|
||||
STUB SetDCPenColor_stub;
|
||||
STUB GetDCBrushColor_stub;
|
||||
STUB GetDCPenColor_stub;
|
||||
STUB AddFontMemResourceEx_stub;
|
||||
STUB RemoveFontMemResourceEx_stub;
|
||||
INT WINAPI AddFontResourceExW_new(LPCWSTR strW, DWORD fl, PVOID pdv);
|
||||
INT WINAPI AddFontResourceW_new(LPCWSTR strW);
|
||||
int WINAPI EnumFontFamiliesExA_new(HDC hdc, LPLOGFONTA pLogfontA, FONTENUMPROCA pEnumFontFamExProc, LPARAM lParam, DWORD dwFlags);
|
||||
int WINAPI EnumFontFamiliesExW_new(HDC hdc, LPLOGFONTW pLogfontW, FONTENUMPROCW pEnumFontFamExProc, LPARAM lParam, DWORD dwFlags);
|
||||
int WINAPI EnumFontFamiliesW_new(HDC hdc, LPCWSTR lpszFamily, FONTENUMPROCW lpEnumFontFamProc, LPARAM lParam);
|
||||
BOOL WINAPI RemoveFontResourceExW_new(LPCWSTR strW, DWORD fl, PVOID pdv);
|
||||
BOOL WINAPI RemoveFontResourceW_new(LPCWSTR strW);
|
||||
HPEN WINAPI ExtCreatePen_fix(DWORD dwPenStyle, DWORD dwWidth, CONST LOGBRUSH *lplb, DWORD dwStyleCount, CONST DWORD *lpStyle);
|
||||
int WINAPI GetObjectW_new(HGDIOBJ hgdiobj, int cbBuffer, LPVOID lpvObject);
|
||||
/*** AUTOGENERATED APILIST DECLARATIONS END ***/
|
||||
|
||||
#endif
|
||||
|
2
apilibs/kexbases/Gdi32/_gdi32_stubs.c
Normal file → Executable file
2
apilibs/kexbases/Gdi32/_gdi32_stubs.c
Normal file → Executable file
@ -23,5 +23,7 @@
|
||||
|
||||
UNIMPL_FUNC(SetDCBrushColor, 2);
|
||||
UNIMPL_FUNC(SetDCPenColor, 2);
|
||||
UNIMPL_FUNC(GetDCBrushColor, 1);
|
||||
UNIMPL_FUNC(GetDCPenColor, 1);
|
||||
UNIMPL_FUNC(AddFontMemResourceEx, 4);
|
||||
UNIMPL_FUNC(RemoveFontMemResourceEx, 1);
|
||||
|
60
apilibs/kexbases/Gdi32/unigdi32.c
Normal file → Executable file
60
apilibs/kexbases/Gdi32/unigdi32.c
Normal file → Executable file
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* KernelEx
|
||||
* Copyright (C) 2009, Xeno86
|
||||
* Copyright (C) 2009, Tihiy
|
||||
*
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
@ -115,16 +116,43 @@ static int CALLBACK EnumFontFamExConv(const LOGFONTA *plfA,
|
||||
return pef->EnumProcW((LOGFONTW*) &elfeW, (TEXTMETRICW*) &ntmeW, FontType, pef->lParam);
|
||||
}
|
||||
|
||||
/* Surprise surprise!
|
||||
* logfont* is optional in EnumFontFamiliesEx on NT
|
||||
* and means - all fonts, all charsets
|
||||
*/
|
||||
|
||||
/* MAKE_EXPORT EnumFontFamiliesExA_new=EnumFontFamiliesExA */
|
||||
int WINAPI EnumFontFamiliesExA_new(HDC hdc, LPLOGFONTA pLogfontA,
|
||||
FONTENUMPROCA pEnumFontFamExProc, LPARAM lParam, DWORD dwFlags)
|
||||
{
|
||||
LOGFONTA logfont;
|
||||
if (!pLogfontA)
|
||||
{
|
||||
memset(&logfont, 0, sizeof(logfont));
|
||||
logfont.lfCharSet = DEFAULT_CHARSET;
|
||||
pLogfontA = &logfont;
|
||||
}
|
||||
return EnumFontFamiliesExA(hdc, pLogfontA, pEnumFontFamExProc, lParam, dwFlags);
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT EnumFontFamiliesExW_new=EnumFontFamiliesExW */
|
||||
int WINAPI EnumFontFamiliesExW_new(HDC hdc, LPLOGFONTW pLogfontW,
|
||||
FONTENUMPROCW pEnumFontFamExProc, LPARAM lParam, DWORD dwFlags)
|
||||
{
|
||||
EnumFamilies_t ef;
|
||||
LOGFONTA logfont;
|
||||
if (pLogfontW)
|
||||
{
|
||||
memcpy(&logfont, pLogfontW, sizeof(LOGFONTA) - LF_FACESIZE);
|
||||
WideCharToMultiByte(CP_ACP, 0, pLogfontW->lfFaceName, -1, logfont.lfFaceName,
|
||||
LF_FACESIZE, NULL, NULL);
|
||||
logfont.lfFaceName[LF_FACESIZE - 1] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
memset(&logfont, 0, sizeof(logfont));
|
||||
logfont.lfCharSet = DEFAULT_CHARSET;
|
||||
}
|
||||
ef.EnumProcW = pEnumFontFamExProc;
|
||||
ef.lParam = lParam;
|
||||
return EnumFontFamiliesExA(hdc, &logfont, EnumFontFamExConv, (LPARAM) &ef, dwFlags);
|
||||
@ -165,3 +193,35 @@ BOOL WINAPI RemoveFontResourceW_new(LPCWSTR strW)
|
||||
file_ALLOC_WtoA(str);
|
||||
return RemoveFontResourceA(strA);
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT ExtCreatePen_fix=ExtCreatePen */
|
||||
HPEN WINAPI ExtCreatePen_fix(
|
||||
DWORD dwPenStyle, // pen style
|
||||
DWORD dwWidth, // pen width
|
||||
CONST LOGBRUSH *lplb, // brush attributes
|
||||
DWORD dwStyleCount, // length of custom style array
|
||||
CONST DWORD *lpStyle // custom style array
|
||||
)
|
||||
{
|
||||
dwPenStyle &= ~PS_USERSTYLE;
|
||||
return ExtCreatePen(dwPenStyle,dwWidth,lplb,dwStyleCount,lpStyle);
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT GetObjectW_new=GetObjectW */
|
||||
int WINAPI GetObjectW_new(
|
||||
HGDIOBJ hgdiobj, // handle to graphics object
|
||||
int cbBuffer, // size of buffer for object information
|
||||
LPVOID lpvObject // buffer for object information
|
||||
)
|
||||
{
|
||||
int type = GetObjectType_fix(hgdiobj);
|
||||
if (type != OBJ_FONT) return GetObjectA(hgdiobj,cbBuffer,lpvObject);
|
||||
if (!lpvObject) return sizeof(LOGFONTW);
|
||||
LOGFONTA fontA = {0};
|
||||
LOGFONTW fontW = {0};
|
||||
if (!GetObjectA(hgdiobj,sizeof(LOGFONTA),&fontA)) return 0; //err not font
|
||||
memcpy(&fontW,&fontA,FIELD_OFFSET(LOGFONTA,lfFaceName));
|
||||
MultiByteToWideChar(CP_ACP,0,fontA.lfFaceName,-1,fontW.lfFaceName,LF_FACESIZE);
|
||||
memcpy(lpvObject,&fontW,cbBuffer);
|
||||
return cbBuffer;
|
||||
}
|
||||
|
0
apilibs/kexbases/Kernel32/CopyFileEx.c
Normal file → Executable file
0
apilibs/kexbases/Kernel32/CopyFileEx.c
Normal file → Executable file
0
apilibs/kexbases/Kernel32/CreateThread_fix.c
Normal file → Executable file
0
apilibs/kexbases/Kernel32/CreateThread_fix.c
Normal file → Executable file
0
apilibs/kexbases/Kernel32/DeleteCriticalSection.c
Normal file → Executable file
0
apilibs/kexbases/Kernel32/DeleteCriticalSection.c
Normal file → Executable file
99
apilibs/kexbases/Kernel32/FileApis_fix.c
Normal file → Executable file
99
apilibs/kexbases/Kernel32/FileApis_fix.c
Normal file → Executable file
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* KernelEx
|
||||
* Copyright (C) 2008-2009, Xeno86
|
||||
* Copyright (C) 2008-2009, Xeno86, Tihiy
|
||||
*
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
@ -38,6 +38,8 @@ HANDLE WINAPI CreateFileA_fix(LPCSTR lpFileName, DWORD dwDesiredAccess,
|
||||
if (oldaccess & FILE_EXECUTE)
|
||||
dwDesiredAccess |= GENERIC_EXECUTE;
|
||||
}
|
||||
//FILE_SHARE_DELETE is not supported
|
||||
dwShareMode &= ~FILE_SHARE_DELETE;
|
||||
// hTemplate has to be NULL on 9x
|
||||
hTemplateFile = NULL;
|
||||
// special case: overlapped I/O
|
||||
@ -69,17 +71,22 @@ BOOL WINAPI ReadFile_fix(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRe
|
||||
if (lpOverlapped && GetLastError() == ERROR_INVALID_PARAMETER)
|
||||
{
|
||||
LONG high = lpOverlapped->OffsetHigh;
|
||||
DWORD nr;
|
||||
SetLastError(lasterr);
|
||||
if ((SetFilePointer(hFile, lpOverlapped->Offset, &high, FILE_BEGIN)
|
||||
== (DWORD)-1 && GetLastError() != NO_ERROR) ||
|
||||
(ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, &nr, 0) && !nr))
|
||||
{
|
||||
SetLastError(ERROR_HANDLE_EOF);
|
||||
== INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR))
|
||||
return FALSE;
|
||||
}
|
||||
*lpNumberOfBytesRead = nr;
|
||||
return TRUE;
|
||||
ResetEvent(lpOverlapped->hEvent);
|
||||
lpOverlapped->Internal = STATUS_PENDING;
|
||||
lpOverlapped->InternalHigh = 0;
|
||||
BOOL result =
|
||||
ReadFile(hFile, lpBuffer, nNumberOfBytesToRead, &lpOverlapped->InternalHigh, 0);
|
||||
lasterr = GetLastError();
|
||||
lpOverlapped->Internal = STATUS_WAIT_0;
|
||||
SetEvent(lpOverlapped->hEvent);
|
||||
SetLastError(lasterr);
|
||||
if (lpNumberOfBytesRead)
|
||||
*lpNumberOfBytesRead = lpOverlapped->InternalHigh;
|
||||
return result;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
@ -99,9 +106,79 @@ BOOL WINAPI WriteFile_fix(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesTo
|
||||
LONG high = lpOverlapped->OffsetHigh;
|
||||
SetLastError(lasterr);
|
||||
if ((SetFilePointer(hFile, lpOverlapped->Offset, &high, FILE_BEGIN)
|
||||
== (DWORD)-1 && GetLastError() != NO_ERROR))
|
||||
== INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR))
|
||||
return FALSE;
|
||||
return WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, 0);
|
||||
ResetEvent(lpOverlapped->hEvent);
|
||||
lpOverlapped->Internal = STATUS_PENDING;
|
||||
lpOverlapped->InternalHigh = 0;
|
||||
BOOL result =
|
||||
WriteFile(hFile, lpBuffer, nNumberOfBytesToWrite, &lpOverlapped->InternalHigh, 0);
|
||||
lasterr = GetLastError();
|
||||
lpOverlapped->Internal = STATUS_WAIT_0;
|
||||
SetEvent(lpOverlapped->hEvent);
|
||||
SetLastError(lasterr);
|
||||
if (lpNumberOfBytesWritten)
|
||||
*lpNumberOfBytesWritten = lpOverlapped->InternalHigh;
|
||||
return result;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT GetTempFileNameA_fix=GetTempFileNameA */
|
||||
UINT WINAPI GetTempFileNameA_fix(LPCSTR lpPathName, LPCSTR lpPrefixString, UINT uUnique, LPTSTR lpTempFileName)
|
||||
{
|
||||
static int g_tempprefix = 0;
|
||||
|
||||
if (!lpPathName)
|
||||
lpPathName = "\\";
|
||||
if (!lpPrefixString)
|
||||
{
|
||||
char temppref[2];
|
||||
g_tempprefix++;
|
||||
g_tempprefix %= 5;
|
||||
temppref[0] = '0' + g_tempprefix;
|
||||
temppref[1] = '\0';
|
||||
lpPrefixString = temppref;
|
||||
}
|
||||
return GetTempFileNameA(lpPathName,lpPrefixString,uUnique,lpTempFileName);
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT GetDiskFreeSpaceA_fix=GetDiskFreeSpaceA */
|
||||
BOOL WINAPI GetDiskFreeSpaceA_fix(LPCSTR lpRootPathName, LPDWORD lpSectorsPerCluster,
|
||||
LPDWORD lpBytesPerSector, LPDWORD lpNumberOfFreeClusters,
|
||||
LPDWORD lpTotalNumberOfClusters)
|
||||
{
|
||||
char newRootPath[4] = { "X:\\" };
|
||||
if (lstrlenA(lpRootPathName) == 2 && lpRootPathName[1] == ':') //GetDiskFreeSpace fails on paths like C:
|
||||
{
|
||||
newRootPath[0] = lpRootPathName[0];
|
||||
lpRootPathName = newRootPath;
|
||||
}
|
||||
BOOL ret = GetDiskFreeSpaceA(lpRootPathName,lpSectorsPerCluster,lpBytesPerSector,lpNumberOfFreeClusters,lpTotalNumberOfClusters);
|
||||
if (!ret) //more suprisingly, it may fail on paths with two extensions (e.g. c:\game.exe.lnk)
|
||||
{
|
||||
char shortPath[MAX_PATH];
|
||||
if (GetShortPathName(lpRootPathName,shortPath,MAX_PATH))
|
||||
{
|
||||
//GetDiskFreeSpace will still fail on short path name, so we check drive root, having path validated
|
||||
newRootPath[0] = shortPath[0];
|
||||
ret = GetDiskFreeSpaceA(newRootPath,lpSectorsPerCluster,lpBytesPerSector,lpNumberOfFreeClusters,lpTotalNumberOfClusters);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT GetDiskFreeSpaceExA_fix=GetDiskFreeSpaceExA */
|
||||
BOOL WINAPI GetDiskFreeSpaceExA_fix(LPCSTR lpDirectoryName, PULARGE_INTEGER lpFreeBytesAvailable,
|
||||
PULARGE_INTEGER lpTotalNumberOfBytes, PULARGE_INTEGER lpTotalNumberOfFreeBytes)
|
||||
{
|
||||
//GetDiskFreeSpaceEx does not fail on paths like C: but still fails on on paths with two extensions
|
||||
BOOL ret = GetDiskFreeSpaceExA(lpDirectoryName,lpFreeBytesAvailable,lpTotalNumberOfBytes,lpTotalNumberOfFreeBytes);
|
||||
if (!ret)
|
||||
{
|
||||
char shortPath[MAX_PATH];
|
||||
if (GetShortPathName(lpDirectoryName,shortPath,MAX_PATH))
|
||||
ret = GetDiskFreeSpaceExA(shortPath,lpFreeBytesAvailable,lpTotalNumberOfBytes,lpTotalNumberOfFreeBytes);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
0
apilibs/kexbases/Kernel32/GetConsoleWindow.c
Normal file → Executable file
0
apilibs/kexbases/Kernel32/GetConsoleWindow.c
Normal file → Executable file
0
apilibs/kexbases/Kernel32/GetFileSizeEx.c
Normal file → Executable file
0
apilibs/kexbases/Kernel32/GetFileSizeEx.c
Normal file → Executable file
73
apilibs/kexbases/Kernel32/GetModuleHandleEx.c
Executable file
73
apilibs/kexbases/Kernel32/GetModuleHandleEx.c
Executable file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* KernelEx
|
||||
* Copyright (C) 2009 Tihiy
|
||||
*
|
||||
* This file is part of KernelEx source code.
|
||||
*
|
||||
* KernelEx is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published
|
||||
* by the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* KernelEx is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with GNU Make; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#undef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0600
|
||||
|
||||
#include <windows.h>
|
||||
#include "common.h"
|
||||
|
||||
/* MAKE_EXPORT GetModuleHandleExA_new=GetModuleHandleExA */
|
||||
BOOL WINAPI GetModuleHandleExA_new(
|
||||
DWORD dwFlags,
|
||||
LPCSTR lpModuleName,
|
||||
HMODULE* phModule
|
||||
)
|
||||
{
|
||||
char buf[MAX_PATH];
|
||||
if (!phModule)
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
*phModule = NULL;
|
||||
if (dwFlags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
if (!VirtualQuery(lpModuleName,&mbi,sizeof(mbi))) return FALSE;
|
||||
*phModule = (HMODULE)mbi.AllocationBase;
|
||||
}
|
||||
else
|
||||
*phModule = GetModuleHandleA(lpModuleName);
|
||||
if (*phModule == NULL || !GetModuleFileNameA(*phModule,buf,MAX_PATH))
|
||||
{
|
||||
*phModule = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
if (!(dwFlags & GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT))
|
||||
LoadLibraryA(buf);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT GetModuleHandleExW_new=GetModuleHandleExW */
|
||||
BOOL WINAPI GetModuleHandleExW_new(
|
||||
DWORD dwFlags,
|
||||
LPCWSTR lpModuleNameW,
|
||||
HMODULE* phModule
|
||||
)
|
||||
{
|
||||
if (dwFlags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS)
|
||||
return GetModuleHandleExA_new(dwFlags,(LPSTR)lpModuleNameW,phModule);
|
||||
ALLOC_WtoA(lpModuleName);
|
||||
return GetModuleHandleExA_new(dwFlags,lpModuleNameA,phModule);
|
||||
}
|
||||
|
0
apilibs/kexbases/Kernel32/GlobalMemoryStatusEx.c
Normal file → Executable file
0
apilibs/kexbases/Kernel32/GlobalMemoryStatusEx.c
Normal file → Executable file
22
apilibs/kexbases/Kernel32/HeapLocks.c
Normal file → Executable file
22
apilibs/kexbases/Kernel32/HeapLocks.c
Normal file → Executable file
@ -49,3 +49,25 @@ BOOL WINAPI HeapUnlock_new(
|
||||
LeaveCriticalSection((CRITICAL_SECTION*)((DWORD)hHeap+0x50));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define ISPOINTER(h) (((ULONG_PTR)(h)&2)==0)
|
||||
|
||||
/* MAKE_EXPORT GlobalLock_fix=GlobalLock */
|
||||
LPVOID WINAPI GlobalLock_fix(
|
||||
HGLOBAL hMem // address of the global memory object
|
||||
)
|
||||
{
|
||||
if (ISPOINTER(hMem))
|
||||
return IsBadReadPtr(hMem, 1) ? NULL : hMem;
|
||||
return GlobalLock(hMem);
|
||||
}
|
||||
|
||||
/* MAKE_EXPORT GlobalUnlock_fix=GlobalUnlock */
|
||||
BOOL WINAPI GlobalUnlock_fix(
|
||||
HGLOBAL hMem // handle to the global memory object
|
||||
)
|
||||
{
|
||||
if (ISPOINTER(hMem))
|
||||
return TRUE;
|
||||
return GlobalUnlock(hMem);
|
||||
}
|
||||
|
0
apilibs/kexbases/Kernel32/InitializeCriticalSectionAndSpinCount.c
Normal file → Executable file
0
apilibs/kexbases/Kernel32/InitializeCriticalSectionAndSpinCount.c
Normal file → Executable file
0
apilibs/kexbases/Kernel32/IsProcessorFeaturePresent.c
Normal file → Executable file
0
apilibs/kexbases/Kernel32/IsProcessorFeaturePresent.c
Normal file → Executable file
21
core/storage.h → apilibs/kexbases/Kernel32/IsWow64Process.c
Normal file → Executable file
21
core/storage.h → apilibs/kexbases/Kernel32/IsWow64Process.c
Normal file → Executable file
@ -19,18 +19,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __STORAGE_H
|
||||
#define __STORAGE_H
|
||||
#include <windows.h>
|
||||
|
||||
class storage
|
||||
/* MAKE_EXPORT IsWow64Process_new=IsWow64Process */
|
||||
BOOL WINAPI IsWow64Process_new(HANDLE hProcess, PBOOL Wow64Process)
|
||||
{
|
||||
public:
|
||||
int size;
|
||||
void* data[1]; //dummy table
|
||||
|
||||
static const int storage_size;
|
||||
static storage* get_storage(bool alloc);
|
||||
static void return_storage();
|
||||
};
|
||||
|
||||
#endif
|
||||
if (!Wow64Process)
|
||||
return FALSE;
|
||||
*Wow64Process = FALSE;
|
||||
return TRUE;
|
||||
}
|
0
apilibs/kexbases/Kernel32/Jobs.c
Normal file → Executable file
0
apilibs/kexbases/Kernel32/Jobs.c
Normal file → Executable file
0
apilibs/kexbases/Kernel32/KEXVersion.c
Normal file → Executable file
0
apilibs/kexbases/Kernel32/KEXVersion.c
Normal file → Executable file
0
apilibs/kexbases/Kernel32/LockFileEx.c
Normal file → Executable file
0
apilibs/kexbases/Kernel32/LockFileEx.c
Normal file → Executable file
0
apilibs/kexbases/Kernel32/MapViewOfFile.c
Normal file → Executable file
0
apilibs/kexbases/Kernel32/MapViewOfFile.c
Normal file → Executable file
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user