1
0
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:
UzixLS
2018-11-03 16:21:13 +03:00
parent d6aad6c6c5
commit 09929b2b7d
392 changed files with 17832 additions and 2491 deletions

View File

@ -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

View File

@ -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

View File

@ -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>

View File

@ -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
@ -324,21 +352,29 @@ SectionEnd
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
View 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
View File

1
apilibs/kexbasen/advapi32/_advapi32_apilist.c Normal file → Executable file
View 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
View 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
View 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
View File

0
apilibs/kexbasen/comdlg32/_comdlg32_apilist.h Normal file → Executable file
View File

0
apilibs/kexbasen/comdlg32/openfilename_fix.c Normal file → Executable file
View File

0
apilibs/kexbasen/comdlg32/unicomdlg32.c Normal file → Executable file
View File

1
apilibs/kexbasen/common.c Normal file → Executable file
View 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);
}

23
apilibs/kexbasen/common.h Normal file → Executable file
View 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,14 +38,17 @@ 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" \
"xor %eax, %eax\n\t" \
"movb $" #params ", %cl\n\t" \
#define UNIMPL_FUNC(name,params) \
__asm__( ".text\n" \
".globl _" #name "_stub@0\n" \
"_" #name "_stub@0:\n\t" \
"xor %eax, %eax\n\t" \
"movb $" #params ", %cl\n\t" \
"jmp _CommonUnimpStub@0\n\t" \
)
#else
@ -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
View File

@ -6,4 +6,4 @@ comdlg32
shell32
rpcrt4
winspool
shlwapi
shfolder

40
apilibs/kexbasen/gdi32/UberGDI.c Normal file → Executable file
View 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
View 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
View 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
View 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);

View 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,&param);
}

View 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);
}

View 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
View 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
View 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;

View 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);
}

File diff suppressed because it is too large Load Diff

View 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);

View 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)

View 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))

View 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
View File

0
apilibs/kexbasen/kexbasen.def Normal file → Executable file
View File

141
apilibs/kexbasen/kexbasen.dsp Normal file → Executable file
View 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
View 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
View 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
View File

0
apilibs/kexbasen/rpcrt4/_rpcrt4_apilist.c Normal file → Executable file
View File

0
apilibs/kexbasen/rpcrt4/_rpcrt4_apilist.h Normal file → Executable file
View File

0
apilibs/kexbasen/rpcrt4/unirpcrt4.c Normal file → Executable file
View File

333
apilibs/kexbasen/shell32/SHGetFolderLocation.c Normal file → Executable file
View File

@ -1,300 +1,89 @@
/*
* 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,
* 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.
* 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 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)
typedef HRESULT (WINAPI *SHGetFolderLocation_t)(HWND, int, HANDLE, DWORD, LPVOID*);
HRESULT WINAPI SHGetFolderLocation_impl(
HWND hwndOwner,
int nFolder,
HANDLE hToken,
DWORD dwReserved,
LPVOID *ppidl
)
{
LPITEMIDLIST pidlOut = NULL;
if (!ppidl)
return E_INVALIDARG;
if (dwReserved)
return E_INVALIDARG;
pidlOut = (LPITEMIDLIST) SHAlloc(size + 5);
if(pidlOut)
{
LPPIDLDATA pData;
LPITEMIDLIST pidlNext;
HRESULT hr = SHGetSpecialFolderLocation_fix(hwndOwner, nFolder, ppidl);
if (!SUCCEEDED(hr))
{
char szPath[MAX_PATH];
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;
hr = SHGetFolderPathA_new(hwndOwner, nFolder, hToken, SHGFP_TYPE_CURRENT, szPath);
if (SUCCEEDED(hr))
{
DWORD attributes = 0;
hr = SHILCreateFromPath((LPWSTR)szPath, (LPITEMIDLIST*)ppidl, &attributes);
}
else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
{
/* unlike SHGetFolderPath, SHGetFolderLocation in shell32
* version 6.0 returns E_FAIL for nonexistent paths
*/
hr = E_FAIL;
}
}
if (*ppidl)
hr = NOERROR;
return hr;
}
LPITEMIDLIST _ILCreateDesktop()
static SHGetFolderLocation_t dld()
{
LPITEMIDLIST ret;
TRACE("()\n");
ret = (LPITEMIDLIST) SHAlloc(2);
if (ret)
ret->mkid.cb = 0;
return ret;
HMODULE h = GetModuleHandle("SHELL32");
SHGetFolderLocation_t pfn = (SHGetFolderLocation_t)
GetProcAddress(h, "SHGetFolderLocation");
if (!pfn)
pfn = SHGetFolderLocation_impl;
return pfn;
}
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(
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:
{
char szPath[MAX_PATH];
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);
}
else if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
{
/* unlike SHGetFolderPath, SHGetFolderLocation in shell32
* version 6.0 returns E_FAIL for nonexistent paths
*/
hr = E_FAIL;
}
}
}
if(*ppidl)
hr = NOERROR;
TRACE("-- (new pidl %p)\n",*ppidl);
return hr;
static SHGetFolderLocation_t SHGetFolderLocation_pfn;
if (!SHGetFolderLocation_pfn)
SHGetFolderLocation_pfn = dld();
return SHGetFolderLocation_pfn(hwndOwner, nFolder, hToken, dwReserved, ppidl);
}

21
apilibs/kexbasen/shell32/SHGetFolderPath.c Normal file → Executable file
View 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);
}
if (!hShfolder)
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);
}

View 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
View 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
View 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;

View File

@ -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

View 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

View File

@ -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
View File

View 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*/);

View 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

View 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);
}

View File

@ -1,59 +1,48 @@
/*
* 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
#define LHE_DISCARDED 0x40
#define LHE_FREEHANDLE 0xFF
#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
{
WORD wBlock;
BYTE bFlags;
BYTE bLocks;
} LHENTRY, *PLHENTRY;
typedef struct
{
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
/*
* 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 <stdio.h>
#include "shlord.h"
#include "common.h"
static HMODULE hShlwapi;
void shlwapi_fatal_error(int funcnum)
{
char msg[256];
sprintf(msg, "kexbasen: Failed to get shlwapi proc: #%i",funcnum);
fatal_error(msg);
}
PVOID WINAPI GetShlwapiProc(int funcnum)
{
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
View 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

View File

@ -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
View File

0
apilibs/kexbasen/unifwd.h Normal file → Executable file
View File

35
apilibs/kexbasen/user32/_user32_apilist.c Normal file → Executable file
View 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
View 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
View 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);

5
apilibs/kexbasen/winspool/DefaultPrinter.c Normal file → Executable file
View File

@ -63,8 +63,9 @@ BOOL WINAPI GetDefaultPrinterW(LPWSTR bufW, LPDWORD sizeW)
if (ret)
{
*sizeW = ABUFtoW(buf, sizeA, *sizeW);
if (!ret)
*sizeW = ABUFtoW(buf, sizeA, 0);
if (*sizeW)
return TRUE;
*sizeW = ABUFtoW(buf, sizeA, 0);
}
return FALSE;
}

28
apilibs/kexbasen/winspool/_winspool_apilist.c Normal file → Executable file
View 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
View 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

View 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);

View 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
View File

0
apilibs/kexbases/Advapi32/RegDisablePredefinedCache.c Normal file → Executable file
View File

0
apilibs/kexbases/Advapi32/RegOpenCurrentUser.c Normal file → Executable file
View File

View 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
View File

9
apilibs/kexbases/Advapi32/_advapi32_apilist.c Normal file → Executable file
View 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
View 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
View 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);

222
apilibs/kexbases/Advapi32/security.c Normal file → Executable file
View 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)
return FALSE;
if (!pSid || nSubAuthorityCount >= SID_MAX_SUB_AUTHORITIES)
{
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
pisid->Revision = SID_REVISION;
pisid->SubAuthorityCount = nSubAuthorityCount;
@ -897,17 +900,18 @@ SetSecurityDescriptorDacl_new (
}
if (!daclpresent)
{ lpsd->Control &= ~SE_DACL_PRESENT;
return TRUE;
{
lpsd->Control &= ~SE_DACL_PRESENT;
return TRUE;
}
lpsd->Control |= SE_DACL_PRESENT;
lpsd->Dacl = dacl;
if (dacldefaulted)
lpsd->Control |= SE_DACL_DEFAULTED;
lpsd->Control |= SE_DACL_DEFAULTED;
else
lpsd->Control &= ~SE_DACL_DEFAULTED;
lpsd->Control &= ~SE_DACL_DEFAULTED;
return TRUE;
}
@ -994,9 +998,87 @@ MakeSelfRelativeSD_new(
IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
IN OUT LPDWORD lpdwBufferLength)
{
FIXME("MakeSelfRelativeSD(%p,%p,%p(%lu))\n", pAbsoluteSecurityDescriptor,
pSelfRelativeSecurityDescriptor, lpdwBufferLength,*lpdwBufferLength);
return TRUE;
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;
}
/******************************************************************************
@ -1013,10 +1095,10 @@ BOOL WINAPI GetSecurityDescriptorControl_new ( PSECURITY_DESCRIPTOR pSecurityDe
*lpdwRevision = lpsd->Revision;
if (*lpdwRevision != SECURITY_DESCRIPTOR_REVISION)
{
SetLastError(ERROR_UNKNOWN_REVISION);
return FALSE;
}
{
SetLastError(ERROR_UNKNOWN_REVISION);
return FALSE;
}
*pControl = lpsd->Control;
@ -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);
}

198
apilibs/kexbases/Advapi32/uniadvapi32.c Normal file → Executable file
View 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.
*
@ -17,7 +18,7 @@
* 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"
@ -31,83 +32,138 @@ 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;
//retry with dynamic buffer
if (ret == ERROR_MORE_DATA)
{
ALLOC_WtoA(lpValueName);
ptr = heapbuf = (BYTE*) HeapAlloc(GetProcessHeap(), 0, bufsize);
if (!heapbuf)
{
return ERROR_NOT_ENOUGH_MEMORY;
}
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)
{
ptr = heapbuf = (BYTE*) HeapAlloc(GetProcessHeap(), 0, bufsize);
if (!heapbuf)
{
return ERROR_NOT_ENOUGH_MEMORY;
}
ret = RegQueryValueExA(hKey, lpValueNameA, lpReserved, &type, ptr, &bufsize);
}
}
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;
}
//retry with dynamic buffer
if (ret == ERROR_MORE_DATA)
{
ptr = heapbuf = (BYTE*) HeapAlloc(GetProcessHeap(), 0, bufsize);
if (!heapbuf)
{
return ERROR_NOT_ENOUGH_MEMORY;
}
ret = RegQueryValueExA(hKey, 0, lpReserved, &type, ptr, &bufsize);
}
}
if (ret != ERROR_SUCCESS) goto _end;
if (type == REG_SZ)
{
if (lpcbData)
{
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;
ret = ERROR_MORE_DATA;
}
SetLastError(gle);
goto _end;
}
*lpcbData = written << 1;
}
}
else
{
if (lpData) memcpy(lpData, ptr, bufsize);
if (lpcbData) *lpcbData = bufsize;
}
_end:
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
MultiByteToWideChar(CP_ACP,0,(LPSTR)ptr,bufsize,(LPWSTR)lpData,*lpcbData/sizeof(WCHAR));
}
*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 = RegEnumValueA(hKey, dwIndex, valnamebuf, &valsize, lpReserved, &type, ptr, &bufsize);
}
//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
{
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
MultiByteToWideChar(CP_ACP,0,(LPSTR)ptr,bufsize,(LPWSTR)lpData,*lpcbData/sizeof(WCHAR));
}
*lpcbData = strsize;
break;
default:
if (lpData)
{
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)--;
}
if (heapbuf) HeapFree(GetProcessHeap(), 0, heapbuf);
return ret;
}

0
apilibs/kexbases/Gdi32/FontResourceExA.c Normal file → Executable file
View File

View 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);
}

View 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
View File

31
apilibs/kexbases/Gdi32/TextOut.c Normal file → Executable file
View 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
View 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
View 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
View 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);

86
apilibs/kexbases/Gdi32/unigdi32.c Normal file → Executable file
View File

@ -1,6 +1,7 @@
/*
* KernelEx
* Copyright (C) 2009, Xeno86
* Copyright (C) 2009, Tihiy
*
* This file is part of KernelEx source code.
*
@ -17,7 +18,7 @@
* 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"
#include "_gdi32_apilist.h"
@ -63,14 +64,14 @@ static int CALLBACK EnumFontFamExConv(const LOGFONTA *plfA,
fontW->elfLogFont.lfFaceName, LF_FACESIZE);
fontW->elfLogFont.lfFaceName[LF_FACESIZE - 1] = 0;
MultiByteToWideChar(CP_ACP, 0, (LPCSTR) fontA->elfFullName, -1,
fontW->elfFullName, LF_FULLFACESIZE);
fontW->elfFullName[LF_FULLFACESIZE - 1] = 0;
MultiByteToWideChar(CP_ACP, 0, (LPCSTR) fontA->elfStyle, -1,
fontW->elfStyle, LF_FACESIZE);
fontW->elfStyle[LF_FACESIZE - 1] = 0;
MultiByteToWideChar(CP_ACP, 0, (LPCSTR) fontA->elfScript, -1,
fontW->elfScript, LF_FACESIZE);
fontW->elfScript[LF_FACESIZE - 1] = 0;
fontW->elfFullName, LF_FULLFACESIZE);
fontW->elfFullName[LF_FULLFACESIZE - 1] = 0;
MultiByteToWideChar(CP_ACP, 0, (LPCSTR) fontA->elfStyle, -1,
fontW->elfStyle, LF_FACESIZE);
fontW->elfStyle[LF_FACESIZE - 1] = 0;
MultiByteToWideChar(CP_ACP, 0, (LPCSTR) fontA->elfScript, -1,
fontW->elfScript, LF_FACESIZE);
fontW->elfScript[LF_FACESIZE - 1] = 0;
tmW->ntmTm.tmHeight = tmA->ntmTm.tmHeight;
tmW->ntmTm.tmAscent = tmA->ntmTm.tmAscent;
@ -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;
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';
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
View File

0
apilibs/kexbases/Kernel32/CreateThread_fix.c Normal file → Executable file
View File

0
apilibs/kexbases/Kernel32/DeleteCriticalSection.c Normal file → Executable file
View File

101
apilibs/kexbases/Kernel32/FileApis_fix.c Normal file → Executable file
View 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);
return FALSE;
}
*lpNumberOfBytesRead = nr;
return TRUE;
== INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR))
return FALSE;
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
View File

0
apilibs/kexbases/Kernel32/GetFileSizeEx.c Normal file → Executable file
View File

View 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
View File

22
apilibs/kexbases/Kernel32/HeapLocks.c Normal file → Executable file
View 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);
}

View File

0
apilibs/kexbases/Kernel32/IsProcessorFeaturePresent.c Normal file → Executable file
View File

View 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
View File

0
apilibs/kexbases/Kernel32/KEXVersion.c Normal file → Executable file
View File

0
apilibs/kexbases/Kernel32/LockFileEx.c Normal file → Executable file
View File

0
apilibs/kexbases/Kernel32/MapViewOfFile.c Normal file → Executable file
View File

Some files were not shown because too many files have changed in this diff Show More