#include <roscfg.h>
#include <limits.h>
#include <ddk/ntddk.h>
-#include <rosrtl/recmutex.h>
+#include <../recmutex/recmutex.h>
#include <roscfg.h>
#include <tcpip.h>
#include <loopback.h>
#include <ddk/ntddk.h>
-#include <rosrtl/recmutex.h>
+#include "recmutex.h"
VOID RecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ) {
RtlZeroMemory( RecMutex, sizeof(*RecMutex) );
<library>ip</library>
<library>oskittcp</library>
<library>ndis</library>
- <library>rosrtl</library>
<library>pseh</library>
<library>ntoskrnl</library>
<library>hal</library>
<directory name="datalink">
<file>lan.c</file>
</directory>
+ <directory name="recmutex">
+ <file>recmutex.c</file>
+ </directory>
<directory name="tcpip">
<file>buffer.c</file>
<file>bug.c</file>
+++ /dev/null
-/* $Id$
- */
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-NTSTATUS NTAPI RtlRosCreateUserThread
-(
- IN HANDLE ProcessHandle,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN BOOLEAN CreateSuspended,
- IN LONG StackZeroBits,
- IN OUT PULONG StackReserve OPTIONAL,
- IN OUT PULONG StackCommit OPTIONAL,
- IN PVOID StartAddress,
- OUT PHANDLE ThreadHandle OPTIONAL,
- OUT PCLIENT_ID ClientId OPTIONAL,
- IN ULONG ParameterCount,
- IN ULONG_PTR * Parameters
-);
-
-NTSTATUS CDECL RtlRosCreateUserThreadVa
-(
- IN HANDLE ProcessHandle,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN BOOLEAN CreateSuspended,
- IN LONG StackZeroBits,
- IN OUT PULONG StackReserve OPTIONAL,
- IN OUT PULONG StackCommit OPTIONAL,
- IN PVOID StartAddress,
- OUT PHANDLE ThreadHandle OPTIONAL,
- OUT PCLIENT_ID ClientId OPTIONAL,
- IN ULONG ParameterCount,
- ...
-);
-
-__declspec(noreturn) VOID NTAPI RtlRosExitUserThread
-(
- IN NTSTATUS Status
-);
-
-NTSTATUS NTAPI RtlRosInitializeContext
-(
- IN HANDLE ProcessHandle,
- OUT PCONTEXT ThreadContext,
- IN PVOID ThreadStartAddress,
- IN PINITIAL_TEB InitialTeb,
- IN ULONG ParameterCount,
- IN ULONG_PTR *Parameters
-);
-
-NTSTATUS NTAPI RtlRosCreateStack
-(
- IN HANDLE ProcessHandle,
- OUT PINITIAL_TEB InitialTeb,
- IN LONG StackZeroBits,
- IN OUT PULONG StackReserve OPTIONAL,
- IN OUT PULONG StackCommit OPTIONAL
-);
-
-NTSTATUS NTAPI RtlRosDeleteStack
-(
- IN HANDLE ProcessHandle,
- IN PINITIAL_TEB InitialTeb
-);
-
-NTSTATUS NTAPI RtlRosFreeUserThreadStack
-(
- IN HANDLE ProcessHandle,
- IN HANDLE ThreadHandle
-);
-
-NTSTATUS NTAPI RtlRosSwitchStackForExit
-(
- IN PVOID StackBase,
- IN SIZE_T StackSize,
- IN VOID (NTAPI * ExitRoutine)(ULONG_PTR Parameter),
- IN ULONG_PTR Parameter
-);
-
-/* Private functions - for ROSRTL internal use only */
-NTSTATUS NTAPI RtlpRosGetStackLimits
-(
- IN PINITIAL_TEB InitialTeb,
- OUT PVOID * StackBase,
- OUT PVOID * StackLimit
-);
-
-NTSTATUS NTAPI RtlpRosValidateLinearUserStack
-(
- IN PVOID StackBase,
- IN PVOID StackLimit,
- IN BOOLEAN Direction
-);
-
-#define RtlpRosValidateTopDownUserStack(__B__, __L__) \
- (RtlpRosValidateLinearUserStack((__B__), (__L__), FALSE))
-
-#define RtlpRosValidateDownTopUserStack(__B__, __L__) \
- (RtlpRosValidateLinearUserStack((__B__), (__L__), TRUE))
-
-#ifdef __cplusplus
-}
-#endif
-
-/* EOF */
<directory name="riched20">
<xi:include href="riched20/riched20.xml" />
</directory>
-<directory name="rosrtl">
- <xi:include href="rosrtl/rosrtl.xml" />
-</directory>
<directory name="rossym">
<xi:include href="rossym/rossym.xml" />
</directory>
<define name="ADNS_JGAA_WIN32" />
<define name="__USE_W32API" />
<library>adns</library>
- <library>rosrtl</library>
<library>ntdll</library>
<library>kernel32</library>
<library>user32</library>
<define name="WINVER">0x0600</define>
<define name="_WIN32_WINNT">0x0501</define>
<library>ntdll</library>
- <library>rosrtl</library>
<library>kernel32</library>
<library>advapi32</library>
<directory name="include">
<define name="WINVER">0x0500</define>
<library>kernel32_base</library>
<library>pseh</library>
- <library>rosrtl</library>
<library>intrlck</library>
<library>ntdll</library>
<linkerflag>-lgcc</linkerflag>
<library>regtests</library>
<library>kernel32_base</library>
<library>pseh</library>
- <library>rosrtl</library>
<library>ntdll</library>
<library>msvcrt</library>
<linkerflag>-lgcc</linkerflag>
<define name="_WIN32_WINNT">0x0502</define>
<define name="_NTOSKRNL_" />
<library>rtl</library>
- <library>rosrtl</library>
<library>intrlck</library>
<library>string</library>
<linkerflag>-lgcc</linkerflag>
+++ /dev/null
-#include <windows.h>\r
-#include <string.h>\r
-\r
-\r
-/***********************************************************************\r
- * MakeSureDirectoryPathExistsExA\r
- *\r
- * If a dir is at the end and the path ends with a backslash, FileAtEnd\r
- * is ignored. If the path doesn't end with a backslash, FileAtEnd is\r
- * used to determine if the last part of the path is a file name or a\r
- * directory.\r
- *\r
- * Path may be absolute or relative to current dir.\r
- */\r
-BOOL STDCALL MakeSureDirectoryPathExistsExA(LPCSTR DirPath, BOOL FileAtEnd)\r
-{\r
- char Path[MAX_PATH];\r
- char *SlashPos = Path;\r
- char Slash;\r
- BOOL bRes;\r
- \r
- strcpy(Path, DirPath);\r
- \r
- while((SlashPos=strpbrk(SlashPos+1,"\\/")))\r
- {\r
- Slash = *SlashPos;\r
- *SlashPos = 0;\r
- \r
- bRes = CreateDirectoryA(Path, NULL);\r
- if (bRes == FALSE && GetLastError() != ERROR_ALREADY_EXISTS)\r
- {\r
- return FALSE;\r
- }\r
- \r
- *SlashPos = Slash;\r
- \r
- if (*(SlashPos+1) == 0) return TRUE;\r
- }\r
-\r
- if (!FileAtEnd)\r
- {\r
- bRes = CreateDirectoryA(Path, NULL);\r
- if (bRes == FALSE && GetLastError() != ERROR_ALREADY_EXISTS)\r
- {\r
- return FALSE;\r
- }\r
- }\r
-\r
- return TRUE;\r
-}\r
-\r
-\r
-\r
-\r
-/***********************************************************************\r
- * MakeSureDirectoryPathExistsExW\r
- *\r
- * If a dir is at the end and the path ends with a backslash, FileAtEnd\r
- * is ignored. If the path doesn't end with a backslash, FileAtEnd is\r
- * used to determine if the last part of the path is a file name or a\r
- * directory.\r
- *\r
- * Path may be absolute or relative to current dir.\r
- */\r
-BOOL STDCALL MakeSureDirectoryPathExistsExW(LPCWSTR DirPath, BOOL FileAtEnd)\r
-{\r
- WCHAR Path[MAX_PATH];\r
- WCHAR *SlashPos = Path;\r
- WCHAR Slash;\r
- BOOL bRes;\r
- \r
- wcscpy(Path, DirPath);\r
- \r
- while((SlashPos=wcspbrk(SlashPos+1,L"\\/")))\r
- {\r
- Slash = *SlashPos;\r
- *SlashPos = 0;\r
- \r
- bRes = CreateDirectoryW(Path, NULL);\r
- if (bRes == FALSE && GetLastError() != ERROR_ALREADY_EXISTS)\r
- {\r
- return FALSE;\r
- }\r
- \r
- *SlashPos = Slash;\r
- \r
- if (*(SlashPos+1) == 0) return TRUE;\r
- }\r
-\r
- if (!FileAtEnd)\r
- {\r
- bRes = CreateDirectoryW(Path, NULL);\r
- if (bRes == FALSE && GetLastError() != ERROR_ALREADY_EXISTS)\r
- {\r
- return FALSE;\r
- }\r
- }\r
-\r
- return TRUE;\r
-}\r
+++ /dev/null
-#if 0
-#include <windows.h>
-#include <ddk/ntifs.h>
-#include <string.h>
-#include <rosrtl/sparse.h>
-
-/*
- * Utility to convert a file to a sparse file
- *
- * IN HANDLE hFile -> Handle to the file to be converted
- *
- * Returns TRUE on success.
- * Returns FALSE on failure, use GetLastError() to get extended error information.
- */
-BOOL
-STDCALL
-SetFileSparse(HANDLE hFile)
-{
- DWORD BytesRet;
- return DeviceIoControl(hFile,
- FSCTL_SET_SPARSE,
- NULL,
- 0,
- NULL,
- 0,
- &BytesRet,
- NULL) != 0;
-}
-
-
-/*
- * Utility to fill a specified range of a file with zeroes.
- *
- * IN HANDLE hFile -> Handle to the file.
- * IN PLARGE_INTEGER pliFileOffset -> Points to a LARGE_INTEGER structure that indicates the file offset of the start of the range in bytes.
- * IN PLARGE_INTEGER pliBeyondFinalZero -> Points to a LARGE_INTEGER structure that indicates the the offset to the first byte beyond the last zeroed byte.
- *
- * Returns TRUE on success.
- * Returns FALSE on failure, use GetLastError() to get extended error information.
- */
-BOOL
-STDCALL
-ZeroFileData(HANDLE hFile,
- PLARGE_INTEGER pliFileOffset,
- PLARGE_INTEGER pliBeyondFinalZero)
-{
- DWORD BytesRet;
- FILE_ZERO_DATA_INFORMATION fzdi;
-
- if(!pliFileOffset || !pliBeyondFinalZero)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- fzdi.FileOffset = *pliFileOffset;
- fzdi.BeyondFinalZero = *pliBeyondFinalZero;
-
- return DeviceIoControl(hFile,
- FSCTL_SET_ZERO_DATA,
- &fzdi,
- sizeof(FILE_ZERO_DATA_INFORMATION),
- NULL,
- 0,
- &BytesRet,
- NULL) != 0;
-}
-
-
-/*
- * Utility to determine the allocated ranges of a sparse file
- *
- * IN HANDLE hFile -> Handle to the file.
- * IN PLARGE_INTEGER pliFileOffset -> Points to a LARGE_INTEGER structure that indicates the portion of the file to search for allocated ranges.
- * IN PLARGE_INTEGER pliLength -> Points to a LARGE_INTEGER structure that indicates it's size.
- * OUT PFILE_ALLOCATED_RANGE_BUFFER lpAllocatedRanges -> Points to a buffer that receives an array of FILE_ALLOCATED_RANGE_BUFFER structures.
- * IN DWORD dwBufferSize -> Size of the output buffer.
- *
- * Returns a nonzero value on success.
- * Returns zero on failure, use GetLastError() to get extended error information.
- */
-DWORD
-STDCALL
-QueryAllocatedFileRanges(HANDLE hFile,
- PLARGE_INTEGER pliFileOffset,
- PLARGE_INTEGER pliLength,
- PFILE_ALLOCATED_RANGE_BUFFER lpAllocatedRanges,
- DWORD dwBufferSize)
-{
- DWORD BytesRet;
- FILE_ALLOCATED_RANGE_BUFFER farb;
-
- if(!pliFileOffset || !pliLength || !lpAllocatedRanges || !dwBufferSize)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- farb.FileOffset = *pliFileOffset;
- farb.Length = *pliLength;
-
- if(DeviceIoControl(hFile,
- FSCTL_QUERY_ALLOCATED_RANGES,
- &farb,
- sizeof(FILE_ALLOCATED_RANGE_BUFFER),
- lpAllocatedRanges,
- dwBufferSize,
- &BytesRet,
- NULL) != 0)
- {
- return BytesRet;
- }
-
- return 0;
-}
-
-#endif
+++ /dev/null
-#if 0
-#include <windows.h>
-#include <string.h>
-#include <rosrtl/devmode.h>
-
-#define SIZEOF_DEVMODEA_300 124
-#define SIZEOF_DEVMODEA_400 148
-#define SIZEOF_DEVMODEA_500 156
-#define SIZEOF_DEVMODEW_300 188
-#define SIZEOF_DEVMODEW_400 212
-#define SIZEOF_DEVMODEW_500 220
-
-void
-RosRtlDevModeA2W ( LPDEVMODEW pW, const LPDEVMODEA pA )
-{
-#define COPYS(f,len) MultiByteToWideChar ( CP_THREAD_ACP, 0, (LPSTR)pA->f, len, pW->f, len )
-#define COPYN(f) pW->f = pA->f
- COPYS(dmDeviceName, CCHDEVICENAME );
- COPYN(dmSpecVersion);
- COPYN(dmDriverVersion);
- switch ( pA->dmSize )
- {
- case SIZEOF_DEVMODEA_300:
- pW->dmSize = SIZEOF_DEVMODEW_300;
- break;
- case SIZEOF_DEVMODEA_400:
- pW->dmSize = SIZEOF_DEVMODEW_400;
- break;
- case SIZEOF_DEVMODEA_500:
- default: /* FIXME what to do??? */
- pW->dmSize = SIZEOF_DEVMODEW_500;
- break;
- }
- COPYN(dmDriverExtra);
- COPYN(dmFields);
- COPYN(dmPosition.x);
- COPYN(dmPosition.y);
- COPYN(dmScale);
- COPYN(dmCopies);
- COPYN(dmDefaultSource);
- COPYN(dmPrintQuality);
- COPYN(dmColor);
- COPYN(dmDuplex);
- COPYN(dmYResolution);
- COPYN(dmTTOption);
- COPYN(dmCollate);
- COPYS(dmFormName,CCHFORMNAME);
- COPYN(dmLogPixels);
- COPYN(dmBitsPerPel);
- COPYN(dmPelsWidth);
- COPYN(dmPelsHeight);
- COPYN(dmDisplayFlags); // aka dmNup
- COPYN(dmDisplayFrequency);
-
- if ( pA->dmSize <= SIZEOF_DEVMODEA_300 )
- return; // we're done with 0x300 fields
-
- COPYN(dmICMMethod);
- COPYN(dmICMIntent);
- COPYN(dmMediaType);
- COPYN(dmDitherType);
- COPYN(dmReserved1);
- COPYN(dmReserved2);
-
- if ( pA->dmSize <= SIZEOF_DEVMODEA_400 )
- return; // we're done with 0x400 fields
-
- COPYN(dmPanningWidth);
- COPYN(dmPanningHeight);
-
- return;
-
-#undef COPYN
-#undef COPYS
-}
-
-
-void
-RosRtlDevModeW2A( LPDEVMODEA pA, const LPDEVMODEW pW )
-{
-#define COPYS(f,len) WideCharToMultiByte( CP_THREAD_ACP, 0, pW->f, len, (LPSTR)pA->f, len, NULL, NULL )
-#define COPYN(f) pA->f = pW->f
- COPYS(dmDeviceName, CCHDEVICENAME );
- COPYN(dmSpecVersion);
- COPYN(dmDriverVersion);
- switch ( pW->dmSize )
- {
- case SIZEOF_DEVMODEW_300:
- pA->dmSize = SIZEOF_DEVMODEA_300;
- break;
- case SIZEOF_DEVMODEW_400:
- pA->dmSize = SIZEOF_DEVMODEA_400;
- break;
- case SIZEOF_DEVMODEW_500:
- default: /* FIXME what to do??? */
- pA->dmSize = SIZEOF_DEVMODEA_500;
- break;
- }
- COPYN(dmDriverExtra);
- COPYN(dmFields);
- COPYN(dmPosition.x);
- COPYN(dmPosition.y);
- COPYN(dmScale);
- COPYN(dmCopies);
- COPYN(dmDefaultSource);
- COPYN(dmPrintQuality);
- COPYN(dmColor);
- COPYN(dmDuplex);
- COPYN(dmYResolution);
- COPYN(dmTTOption);
- COPYN(dmCollate);
- COPYS(dmFormName,CCHFORMNAME);
- COPYN(dmLogPixels);
- COPYN(dmBitsPerPel);
- COPYN(dmPelsWidth);
- COPYN(dmPelsHeight);
- COPYN(dmDisplayFlags); // aka dmNup
- COPYN(dmDisplayFrequency);
-
- if ( pW->dmSize <= SIZEOF_DEVMODEW_300 )
- return; // we're done with 0x300 fields
-
- COPYN(dmICMMethod);
- COPYN(dmICMIntent);
- COPYN(dmMediaType);
- COPYN(dmDitherType);
- COPYN(dmReserved1);
- COPYN(dmReserved2);
-
- if ( pW->dmSize <= SIZEOF_DEVMODEW_400 )
- return; // we're done with 0x400 fields
-
- COPYN(dmPanningWidth);
- COPYN(dmPanningHeight);
-
- return;
-
-#undef COPYN
-#undef COPYS
-}
-
-#undef SIZEOF_DEVMODEA_300
-#undef SIZEOF_DEVMODEA_400
-#undef SIZEOF_DEVMODEA_500
-#undef SIZEOF_DEVMODEW_300
-#undef SIZEOF_DEVMODEW_400
-#undef SIZEOF_DEVMODEW_500
-#endif
+++ /dev/null
-#if 0
-#include <windows.h>
-#include <string.h>
-#include <rosrtl/logfont.h>
-
-void
-RosRtlLogFontA2W ( LPLOGFONTW pW, const LOGFONTA *pA )
-{
-#define COPYS(f,len) MultiByteToWideChar ( CP_THREAD_ACP, 0, pA->f, len, pW->f, len )
-#define COPYN(f) pW->f = pA->f
-
- COPYN(lfHeight);
- COPYN(lfWidth);
- COPYN(lfEscapement);
- COPYN(lfOrientation);
- COPYN(lfWeight);
- COPYN(lfItalic);
- COPYN(lfUnderline);
- COPYN(lfStrikeOut);
- COPYN(lfCharSet);
- COPYN(lfOutPrecision);
- COPYN(lfClipPrecision);
- COPYN(lfQuality);
- COPYN(lfPitchAndFamily);
- COPYS(lfFaceName,LF_FACESIZE);
-
-#undef COPYN
-#undef COPYS
-}
-
-void
-RosRtlLogFontW2A ( LPLOGFONTA pA, const LOGFONTW *pW )
-{
-#define COPYS(f,len) WideCharToMultiByte ( CP_THREAD_ACP, 0, pW->f, len, pA->f, len, NULL, NULL )
-#define COPYN(f) pA->f = pW->f
-
- COPYN(lfHeight);
- COPYN(lfWidth);
- COPYN(lfEscapement);
- COPYN(lfOrientation);
- COPYN(lfWeight);
- COPYN(lfItalic);
- COPYN(lfUnderline);
- COPYN(lfStrikeOut);
- COPYN(lfCharSet);
- COPYN(lfOutPrecision);
- COPYN(lfClipPrecision);
- COPYN(lfQuality);
- COPYN(lfPitchAndFamily);
- COPYS(lfFaceName,LF_FACESIZE);
-
-#undef COPYN
-#undef COPYS
-}
-#endif
+++ /dev/null
-#if 0
-#include <windows.h>
-#define NTOS_MODE_USER
-#include <ndk/ntndk.h>
-#include <rosrtl/string.h>
-
-/*
- * Utility function to read a value from the registry more easily.
- *
- * IN PUNICODE_STRING KeyName -> Name of key to open
- * IN PUNICODE_STRING ValueName -> Name of value to open
- * OUT PUNICODE_STRING ReturnedValue -> String contained in registry
- *
- * Returns NTSTATUS
- */
-
-NTSTATUS NTAPI RosReadRegistryValue( PUNICODE_STRING KeyName,
- PUNICODE_STRING ValueName,
- PUNICODE_STRING ReturnedValue ) {
- NTSTATUS Status;
- HANDLE KeyHandle;
- OBJECT_ATTRIBUTES KeyAttributes;
- PKEY_VALUE_PARTIAL_INFORMATION KeyValuePartialInfo;
- ULONG Length = 0;
- ULONG ResLength = 0;
- UNICODE_STRING Temp;
-
- InitializeObjectAttributes(&KeyAttributes, KeyName, OBJ_CASE_INSENSITIVE,
- NULL, NULL);
- Status = ZwOpenKey(&KeyHandle, KEY_ALL_ACCESS, &KeyAttributes);
- if( !NT_SUCCESS(Status) ) {
- return Status;
- }
-
- Status = ZwQueryValueKey(KeyHandle, ValueName, KeyValuePartialInformation,
- 0,
- 0,
- &ResLength);
-
- if( Status != STATUS_BUFFER_TOO_SMALL ) {
- NtClose(KeyHandle);
- return Status;
- }
-
- ResLength += sizeof( *KeyValuePartialInfo );
- KeyValuePartialInfo =
- RtlAllocateHeap(GetProcessHeap(), 0, ResLength);
- Length = ResLength;
-
- if( !KeyValuePartialInfo ) {
- NtClose(KeyHandle);
- return STATUS_NO_MEMORY;
- }
-
- Status = ZwQueryValueKey(KeyHandle, ValueName, KeyValuePartialInformation,
- (PVOID)KeyValuePartialInfo,
- Length,
- &ResLength);
-
- if( !NT_SUCCESS(Status) ) {
- NtClose(KeyHandle);
- RtlFreeHeap(GetProcessHeap(),0,KeyValuePartialInfo);
- return Status;
- }
-
- Temp.Length = Temp.MaximumLength = KeyValuePartialInfo->DataLength;
- Temp.Buffer = (PWCHAR)KeyValuePartialInfo->Data;
-
- /* At this point, KeyValuePartialInfo->Data contains the key data */
- RtlInitUnicodeString(ReturnedValue,L"");
- RosAppendUnicodeString(ReturnedValue,&Temp,FALSE);
-
- RtlFreeHeap(GetProcessHeap(),0,KeyValuePartialInfo);
- NtClose(KeyHandle);
-
- return Status;
-}
-#endif
-
+++ /dev/null
-<module name="rosrtl" type="staticlibrary">
- <define name="__USE_W32API" />
- <directory name="file">
- <file>sparse.c</file>
- </directory>
- <directory name="misc">
- <file>devmode.c</file>
- <file>logfont.c</file>
- <file>qsort.c</file>
- </directory>
- <directory name="recmutex">
- <file>recmutex.c</file>
- </directory>
- <directory name="registry">
- <file>registry.c</file>
- </directory>
- <directory name="string">
- <file>append.c</file>
- <file>resstr.c</file>
- </directory>
- <directory name="thread">
- <directory name="i386">
- <file>context.c</file>
- <file>stackexit.S</file>
- </directory>
- <file>create.c</file>
- <file>exit.c</file>
- <file>linearstack.c</file>
- <file>priv.c</file>
- <file>stack.c</file>
- </directory>
-</module>
+++ /dev/null
-#include <windows.h>
-#define NTOS_MODE_USER
-#include <ndk/ntndk.h>
-
-/*
- * Utility to copy and append two unicode strings.
- *
- * IN OUT PUNICODE_STRING ResultFirst -> First string and result
- * IN PUNICODE_STRING Second -> Second string to append
- * IN BOOL Deallocate -> TRUE: Deallocate First string before
- * overwriting.
- *
- * Returns NTSTATUS.
- */
-
-NTSTATUS NTAPI RosAppendUnicodeString(PUNICODE_STRING ResultFirst,
- PUNICODE_STRING Second,
- BOOL Deallocate) {
- NTSTATUS Status;
- PWSTR new_string =
- RtlAllocateHeap(GetProcessHeap(),0,
- (ResultFirst->Length + Second->Length + sizeof(WCHAR)));
- if( !new_string ) {
- return STATUS_NO_MEMORY;
- }
- memcpy( new_string, ResultFirst->Buffer,
- ResultFirst->Length );
- memcpy( new_string + ResultFirst->Length / sizeof(WCHAR),
- Second->Buffer,
- Second->Length );
- if( Deallocate ) RtlFreeUnicodeString(ResultFirst);
- ResultFirst->Length += Second->Length;
- ResultFirst->MaximumLength = ResultFirst->Length;
- new_string[ResultFirst->Length / sizeof(WCHAR)] = 0;
- Status = RtlCreateUnicodeString(ResultFirst,new_string) ?
- STATUS_SUCCESS : STATUS_NO_MEMORY;
- RtlFreeHeap(GetProcessHeap(),0,new_string);
- return Status;
-}
+++ /dev/null
-#include <windows.h>
-
-/*
- * Utility to measure the length of a string resource
- *
- * IN HINSTANCE hInst -> Instance of the module
- * IN UINT uID -> ID of the string to measure
- *
- * Returns the number of characters not including the null-terminator.
- * Returns -1 on failure.
- */
-int
-RosLenOfStrResource(HINSTANCE hInst, UINT uID)
-{
- HRSRC hrSrc;
- HGLOBAL hRes;
- LPWSTR lpName, lpStr;
-
- if(hInst == NULL)
- {
- return -1;
- }
-
- /* There are always blocks of 16 strings */
- lpName = (LPWSTR)MAKEINTRESOURCE((uID >> 4) + 1);
-
- /* Find the string table block */
- if((hrSrc = FindResourceW(hInst, lpName, (LPWSTR)RT_STRING)) &&
- (hRes = LoadResource(hInst, hrSrc)) &&
- (lpStr = LockResource(hRes)))
- {
- UINT x;
-
- /* Find the string we're looking for */
- uID &= 0xF; /* position in the block, same as % 16 */
- for(x = 0; x < uID; x++)
- {
- lpStr += (*lpStr) + 1;
- }
-
- /* Found the string */
- return (int)(*lpStr);
- }
- return -1;
-}
-
-/*
- * Utility to allocate and load a string from the string table
- *
- * OUT LPSTR *lpTarget -> Address to a variable that will get the address to the string allocated
- * IN HINSTANCE hInst -> Instance of the module
- * IN UINT uID -> ID of the string to measure
- *
- * Returns the number of characters not including the null-terminator.
- * Returns 0 on failure. Use LocalFree() to free the memory allocated.
- */
-int
-RosAllocAndLoadStringA(LPSTR *lpTarget, HINSTANCE hInst, UINT uID)
-{
- int ln;
-
- ln = RosLenOfStrResource(hInst, uID);
- if(ln++ > 0)
- {
- (*lpTarget) = (LPSTR)LocalAlloc(LMEM_FIXED, ln * sizeof(CHAR));
- if((*lpTarget) != NULL)
- {
- int Ret;
- if(!(Ret = LoadStringA(hInst, uID, *lpTarget, ln)))
- {
- LocalFree((HLOCAL)(*lpTarget));
- }
- return Ret;
- }
- }
- return 0;
-}
-
-/*
- * Utility to allocate and load a string from the string table
- *
- * OUT LPSTR *lpTarget -> Address to a variable that will get the address to the string allocated
- * IN HINSTANCE hInst -> Instance of the module
- * IN UINT uID -> ID of the string to measure
- *
- * Returns the number of characters not including the null-terminator.
- * Returns 0 on failure. Use LocalFree() to free the memory allocated.
- */
-int
-RosAllocAndLoadStringW(LPWSTR *lpTarget, HINSTANCE hInst, UINT uID)
-{
- int ln;
-
- ln = RosLenOfStrResource(hInst, uID);
- if(ln++ > 0)
- {
- (*lpTarget) = (LPWSTR)LocalAlloc(LMEM_FIXED, ln * sizeof(WCHAR));
- if((*lpTarget) != NULL)
- {
- int Ret;
- if(!(Ret = LoadStringW(hInst, uID, *lpTarget, ln)))
- {
- LocalFree((HLOCAL)(*lpTarget));
- }
- return Ret;
- }
- }
- return 0;
-}
-
-/*
- * Utility to allocate memory and format a string
- *
- * OUT LPSTR *lpTarget -> Address to a variable that will get the address to the string allocated
- * IN LPSTR lpFormat -> String which is to be formatted with the arguments given
- *
- * Returns the number of characters in lpTarget not including the null-terminator.
- * Returns 0 on failure. Use LocalFree() to free the memory allocated.
- */
-DWORD
-RosFormatStrA(LPSTR *lpTarget, LPSTR lpFormat, ...)
-{
- DWORD Ret;
- va_list lArgs;
-
- va_start(lArgs, lpFormat);
- /* let's use FormatMessage to format it because it has the ability to allocate
- memory automatically */
- Ret = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
- lpFormat, 0, 0, (LPSTR)lpTarget, 0, &lArgs);
- va_end(lArgs);
-
- return Ret;
-}
-
-/*
- * Utility to allocate memory and format a string
- *
- * OUT LPSTR *lpTarget -> Address to a variable that will get the address to the string allocated
- * IN LPSTR lpFormat -> String which is to be formatted with the arguments given
- *
- * Returns the number of characters in lpTarget not including the null-terminator.
- * Returns 0 on failure. Use LocalFree() to free the memory allocated.
- */
-DWORD
-RosFormatStrW(LPWSTR *lpTarget, LPWSTR lpFormat, ...)
-{
- DWORD Ret;
- va_list lArgs;
-
- va_start(lArgs, lpFormat);
- /* let's use FormatMessage to format it because it has the ability to allocate
- memory automatically */
- Ret = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
- lpFormat, 0, 0, (LPWSTR)lpTarget, 0, &lArgs);
- va_end(lArgs);
-
- return Ret;
-}
-
-/*
- * Utility to allocate memory, load a string from the resources and format it
- *
- * IN HINSTANCE hInst -> Instance of the module
- * IN UINT uID -> ID of the string to measure
- * OUT LPSTR *lpTarget -> Address to a variable that will get the address to the string allocated
- *
- * Returns the number of characters in lpTarget not including the null-terminator.
- * Returns 0 on failure. Use LocalFree() to free the memory allocated.
- */
-DWORD
-RosLoadAndFormatStrA(HINSTANCE hInst, UINT uID, LPSTR *lpTarget, ...)
-{
- DWORD Ret = 0;
- LPSTR lpFormat;
- va_list lArgs;
-
- if(RosAllocAndLoadStringA(&lpFormat, hInst, uID) > 0)
- {
- va_start(lArgs, lpTarget);
- /* let's use FormatMessage to format it because it has the ability to allocate
- memory automatically */
- Ret = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
- lpFormat, 0, 0, (LPSTR)lpTarget, 0, &lArgs);
- va_end(lArgs);
-
- LocalFree((HLOCAL)lpFormat);
- }
-
- return Ret;
-}
-
-/*
- * Utility to allocate memory, load a string from the resources and format it
- *
- * IN HINSTANCE hInst -> Instance of the module
- * IN UINT uID -> ID of the string to measure
- * OUT LPSTR *lpTarget -> Address to a variable that will get the address to the string allocated
- *
- * Returns the number of characters in lpTarget not including the null-terminator.
- * Returns 0 on failure. Use LocalFree() to free the memory allocated.
- */
-DWORD
-RosLoadAndFormatStrW(HINSTANCE hInst, UINT uID, LPWSTR *lpTarget, ...)
-{
- DWORD Ret = 0;
- LPWSTR lpFormat;
- va_list lArgs;
-
- if(RosAllocAndLoadStringW(&lpFormat, hInst, uID) > 0)
- {
- va_start(lArgs, lpTarget);
- /* let's use FormatMessage to format it because it has the ability to allocate
- memory automatically */
- Ret = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_STRING,
- lpFormat, 0, 0, (LPWSTR)lpTarget, 0, &lArgs);
- va_end(lArgs);
-
- LocalFree((HLOCAL)lpFormat);
- }
-
- return Ret;
-}
-
+++ /dev/null
-/* $Id$
-*/
-/*
-*/
-
-#include <windows.h>
-#define NTOS_MODE_USER
-#include <ndk/ntndk.h>
-
-#define NDEBUG
-#include <debug.h>
-
-#include <rosrtl/thread.h>
-
-NTSTATUS STDCALL
-RtlRosCreateUserThread
-(
- IN HANDLE ProcessHandle,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN BOOLEAN CreateSuspended,
- IN LONG StackZeroBits,
- IN OUT PULONG StackReserve OPTIONAL,
- IN OUT PULONG StackCommit OPTIONAL,
- IN PVOID StartAddress,
- OUT PHANDLE ThreadHandle OPTIONAL,
- OUT PCLIENT_ID ClientId OPTIONAL,
- IN ULONG ParameterCount,
- IN ULONG_PTR * Parameters
-)
-{
- INITIAL_TEB usUserInitialTeb;
- CONTEXT ctxInitialContext;
- NTSTATUS nErrCode;
- HANDLE hThread;
- CLIENT_ID cidClientId;
-
- if(ThreadHandle == NULL) ThreadHandle = &hThread;
- if(ClientId == NULL) ClientId = &cidClientId;
-
- /* allocate the stack for the thread */
- nErrCode = RtlRosCreateStack
- (
- ProcessHandle,
- &usUserInitialTeb,
- StackZeroBits,
- StackReserve,
- StackCommit
- );
-
- /* failure */
- if(!NT_SUCCESS(nErrCode)) goto l_Fail;
-
- /* initialize the registers and stack for the thread */
- nErrCode = RtlRosInitializeContext
- (
- ProcessHandle,
- &ctxInitialContext,
- StartAddress,
- &usUserInitialTeb,
- ParameterCount,
- Parameters
- );
-
- /* failure */
- if(!NT_SUCCESS(nErrCode)) goto l_Fail;
-
- /* create the thread object */
- nErrCode = NtCreateThread
- (
- ThreadHandle,
- THREAD_ALL_ACCESS,
- ObjectAttributes,
- ProcessHandle,
- ClientId,
- &ctxInitialContext,
- &usUserInitialTeb,
- CreateSuspended
- );
-
- /* failure */
- if(!NT_SUCCESS(nErrCode)) goto l_Fail;
-
- /* success */
- return STATUS_SUCCESS;
-
- /* failure */
-l_Fail:
- ASSERT(!NT_SUCCESS(nErrCode));
-
- /* deallocate the stack */
- RtlRosDeleteStack(ProcessHandle, &usUserInitialTeb);
-
- return nErrCode;
-}
-
-NTSTATUS CDECL
-RtlRosCreateUserThreadVa
-(
- IN HANDLE ProcessHandle,
- IN POBJECT_ATTRIBUTES ObjectAttributes,
- IN BOOLEAN CreateSuspended,
- IN LONG StackZeroBits,
- IN OUT PULONG StackReserve OPTIONAL,
- IN OUT PULONG StackCommit OPTIONAL,
- IN PVOID StartAddress,
- OUT PHANDLE ThreadHandle OPTIONAL,
- OUT PCLIENT_ID ClientId OPTIONAL,
- IN ULONG ParameterCount,
- ...
-)
-{
- va_list vaArgs;
- NTSTATUS nErrCode;
-
- va_start(vaArgs, ParameterCount);
-
- /*
- FIXME: this code makes several non-portable assumptions:
- - all parameters are passed on the stack
- - the stack is a contiguous array of cells as large as an ULONG_PTR
- - the stack grows downwards
-
- This happens to work on the Intel x86, but is likely to bomb horribly on most
- other platforms
- */
- nErrCode = RtlRosCreateUserThread
- (
- ProcessHandle,
- ObjectAttributes,
- CreateSuspended,
- StackZeroBits,
- StackReserve,
- StackCommit,
- StartAddress,
- ThreadHandle,
- ClientId,
- ParameterCount,
- (ULONG_PTR *)vaArgs
- );
-
- va_end(vaArgs);
-
- return nErrCode;
-}
-
-/* EOF */
+++ /dev/null
-/* $Id$
-*/
-/*
-*/
-
-#include <windows.h>
-#define NTOS_MODE_USER
-#include <ndk/ntndk.h>
-
-#define NDEBUG
-#include <debug.h>
-
-#include <rosrtl/thread.h>
-
-static VOID NTAPI RtlRosExitUserThread_Stage2
-(
- IN ULONG_PTR Status
-)
-{
- RtlRosFreeUserThreadStack(NtCurrentProcess(), NtCurrentThread());
- NtTerminateThread(NtCurrentThread(), Status);
-}
-
-__declspec(noreturn) VOID NTAPI RtlRosExitUserThread
-(
- IN NTSTATUS Status
-)
-{
- RtlRosSwitchStackForExit
- (
- NtCurrentTeb()->StaticUnicodeBuffer,
- sizeof(NtCurrentTeb()->StaticUnicodeBuffer),
- RtlRosExitUserThread_Stage2,
- Status
- );
-
- for(;;);
-}
-
-/* EOF */
+++ /dev/null
-/* $Id$
-*/
-/*
-*/
-
-#include <windows.h>
-#define NTOS_MODE_USER
-#include <ndk/ntndk.h>
-
-#include <rosrtl/thread.h>
-#include <debug.h>
-
-NTSTATUS NTAPI
-RtlRosInitializeContext
-(
- IN HANDLE ProcessHandle,
- OUT PCONTEXT Context,
- IN PVOID StartAddress,
- IN PINITIAL_TEB InitialTeb,
- IN ULONG ParameterCount,
- IN ULONG_PTR * Parameters
-)
-{
- static PVOID s_pRetAddr = (PVOID)0xDEADBEEF;
-
- ULONG nDummy;
- SIZE_T nParamsSize = ParameterCount * sizeof(ULONG_PTR);
- NTSTATUS nErrCode;
- PVOID pStackBase;
- PVOID pStackLimit;
-
- /* Intel x86: linear top-down stack, all parameters passed on the stack */
- /* get the stack base and limit */
- nErrCode = RtlpRosGetStackLimits(InitialTeb, &pStackBase, &pStackLimit);
-
- /* failure */
- if(!NT_SUCCESS(nErrCode)) return nErrCode;
-
- /* validate the stack */
- nErrCode = RtlpRosValidateTopDownUserStack(pStackBase, pStackLimit);
-
- /* failure */
- if(!NT_SUCCESS(nErrCode)) return nErrCode;
-
- /* too many parameters */
- if((nParamsSize + sizeof(ULONG_PTR)) > (SIZE_T)((ULONG_PTR)pStackBase - (ULONG_PTR)pStackLimit))
- return STATUS_STACK_OVERFLOW;
-
- memset(Context, 0, sizeof(CONTEXT));
-
- /* initialize the context */
- Context->ContextFlags = CONTEXT_FULL;
- Context->FloatSave.ControlWord = FLOAT_SAVE_CONTROL;
- Context->FloatSave.StatusWord = FLOAT_SAVE_STATUS;
- Context->FloatSave.TagWord = FLOAT_SAVE_TAG;
- Context->FloatSave.DataSelector = FLOAT_SAVE_DATA;
- Context->Eip = (ULONG_PTR)StartAddress;
- Context->SegGs = USER_DS;
- Context->SegFs = TEB_SELECTOR;
- Context->SegEs = USER_DS;
- Context->SegDs = USER_DS;
- Context->SegCs = USER_CS;
- Context->SegSs = USER_DS;
- Context->Esp = (ULONG_PTR)pStackBase - (nParamsSize + sizeof(ULONG_PTR));
- Context->EFlags = ((ULONG_PTR)1 << 1) | ((ULONG_PTR)1 << 9);
-
- /* write the parameters */
- nErrCode = NtWriteVirtualMemory
- (
- ProcessHandle,
- ((PUCHAR)pStackBase) - nParamsSize,
- Parameters,
- nParamsSize,
- &nDummy
- );
-
- /* failure */
- if(!NT_SUCCESS(nErrCode)) return nErrCode;
-
- /* write the return address */
- return NtWriteVirtualMemory
- (
- ProcessHandle,
- ((PUCHAR)pStackBase) - (nParamsSize + sizeof(ULONG_PTR)),
- &s_pRetAddr,
- sizeof(s_pRetAddr),
- &nDummy
- );
-}
-
-/* EOF */
+++ /dev/null
-.globl _RtlRosSwitchStackForExit@16
-
-_RtlRosSwitchStackForExit@16:
- movl 0x10(%esp), %edx /* Parameter */
- movl 0xC(%esp), %eax /* ExitRoutine */
- movl 0x8(%esp), %ecx /* StackSize */
- movl 0x4(%esp), %esp /* StackBase */
- addl %ecx, %esp
- subl $0x4, %esp
- pushl %edx
- call *%eax
-
-/* EOF */
+++ /dev/null
-/* $Id$
-*/
-/*
-*/
-
-#include <windows.h>
-#define NTOS_MODE_USER
-#include <ndk/ntndk.h>
-#include <rosrtl/thread.h>
-
-NTSTATUS NTAPI RtlpRosValidateLinearUserStack
-(
- IN PVOID StackBase,
- IN PVOID StackLimit,
- IN BOOLEAN Direction
-)
-{
- /* the stack has a null or negative (relatively to its direction) length */
- /*
- Direction: TRUE for down-top, FALSE for top-down
-
- Direction == TRUE and positive stack size: OK
- Direction == TRUE and negative stack size: error
- Direction == FALSE and positive stack size: error
- Direction == FALSE and negative stack size: OK
- */
- if
- (
- StackBase == StackLimit ||
- (Direction ^ ((PCHAR)StackBase < (PCHAR)StackLimit))
- )
- return STATUS_BAD_INITIAL_STACK;
-
- /* valid stack */
- return STATUS_SUCCESS;
-}
-
-/* EOF */
+++ /dev/null
-#if 0
-#include <windows.h>
-#include <rosrtl/priv.h>
-
-/*
- * Utility to copy and enable thread privileges
- *
- * OUT HANDLE *hPreviousToken -> Pointer to a variable that receives the previous token handle
- * IN LUID *Privileges -> Points to an array of privileges to be enabled
- * IN DWORD PrivilegeCount -> Number of the privileges in the array
- *
- * Returns TRUE on success and copies the thread token (if any) handle that was active before impersonation.
- */
-BOOL
-RosEnableThreadPrivileges(HANDLE *hPreviousToken,
- LUID *Privileges,
- DWORD PrivilegeCount)
-{
- HANDLE hToken;
-
- if(hPreviousToken == NULL ||
- Privileges == NULL || PrivilegeCount == 0)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- /* Just open the thread token, we'll duplicate the handle later */
- if(OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE, FALSE, &hToken))
- {
- PTOKEN_PRIVILEGES privs;
- PLUID_AND_ATTRIBUTES la;
- HANDLE hNewToken;
- BOOL Ret;
-
- /* duplicate the token handle */
- if(!DuplicateTokenEx(hToken, TOKEN_IMPERSONATE, NULL, SecurityImpersonation,
- TokenImpersonation, &hNewToken))
- {
- CloseHandle(hToken);
- return FALSE;
- }
-
- /* Allocate the required space for the privilege list */
- privs = (PTOKEN_PRIVILEGES)LocalAlloc(LPTR, sizeof(TOKEN_PRIVILEGES) +
- ((PrivilegeCount - 1) * sizeof(LUID_AND_ATTRIBUTES)));
- if(privs == NULL)
- {
- CloseHandle(hNewToken);
- CloseHandle(hToken);
- return FALSE;
- }
-
- /* Build the privilege list */
- privs->PrivilegeCount = PrivilegeCount;
- for(la = privs->Privileges; PrivilegeCount-- > 0; la++)
- {
- la->Luid = *(Privileges++);
- la->Attributes = SE_PRIVILEGE_ENABLED;
- }
-
- /* Enable the token privileges */
- if(!AdjustTokenPrivileges(hNewToken, FALSE, privs, 0, NULL, NULL))
- {
- LocalFree((HLOCAL)privs);
- CloseHandle(hNewToken);
- CloseHandle(hToken);
- return FALSE;
- }
-
- /* we don't need the privileges list anymore */
- LocalFree((HLOCAL)privs);
-
- /* Perform the impersonation */
- Ret = SetThreadToken(NULL, hNewToken);
-
- if(Ret)
- {
- /* only copy the previous token handle on success */
- *hPreviousToken = hToken;
- }
- else
- {
- /* We don't return the previous token handle on failure, so close it here */
- CloseHandle(hToken);
- }
-
- /* We don't need the handle to the new token anymore */
- CloseHandle(hNewToken);
-
- return Ret;
- }
-
- return FALSE;
-}
-
-
-/*
- * Utility to reset the thread privileges previously changed with RosEnableThreadPrivileges()
- *
- * IN HANDLE hToken -> Handle of the thread token to be restored
- *
- * Returns TRUE on success.
- */
-BOOL
-RosResetThreadPrivileges(HANDLE hToken)
-{
- if(hToken != INVALID_HANDLE_VALUE)
- {
- BOOL Ret;
-
- /* Set the previous token handle */
- Ret = SetThreadToken(NULL, hToken);
-
- /* We don't need the handle anymore, close it */
- CloseHandle(hToken);
- return Ret;
- }
- return FALSE;
-}
-#endif
-
+++ /dev/null
-/* $Id$
-*/
-/*
-*/
-
-#include <windows.h>
-#define NTOS_MODE_USER
-#include <ndk/ntndk.h>
-
-#define NDEBUG
-#include <debug.h>
-
-#include <rosrtl/thread.h>
-
-#define ROUNDUP(a,b) ((((a)+(b)-1)/(b))*(b))
-
-NTSTATUS NTAPI RtlRosCreateStack
-(
- IN HANDLE ProcessHandle,
- OUT PINITIAL_TEB InitialTeb,
- IN LONG StackZeroBits,
- IN OUT PULONG StackReserve OPTIONAL,
- IN OUT PULONG StackCommit OPTIONAL
-)
-{
- /* FIXME: read the defaults from the executable image */
- ULONG_PTR nStackReserve = 0x100000;
- /* FIXME: when we finally have exception handling, make this PAGE_SIZE */
- ULONG_PTR nStackCommit = 0x100000;
- NTSTATUS nErrCode;
-
- if(*StackReserve == 0) StackReserve = &nStackReserve;
- else *StackReserve = ROUNDUP(*StackReserve, PAGE_SIZE);
-
- if(*StackCommit == 0) StackCommit = &nStackCommit;
- else *StackCommit = ROUNDUP(*StackCommit, PAGE_SIZE);
-#if 0
- /* the stack commit size must be equal to or less than the reserve size */
- if(*StackCommit > *StackReserve) *StackCommit = *StackReserve;
-#else
- /* FIXME: no SEH, no guard pages */
- *StackCommit = *StackReserve;
-#endif
-
- /* FIXME: this code assumes a stack growing downwards */
- /* fixed stack */
- if(*StackCommit == *StackReserve)
- {
- InitialTeb->StackBase = NULL;
- InitialTeb->StackLimit = NULL;
- InitialTeb->AllocatedStackBase = NULL;
-
- InitialTeb->PreviousStackLimit = NULL;
-
- /* allocate the stack */
- nErrCode = NtAllocateVirtualMemory
- (
- ProcessHandle,
- &(InitialTeb->PreviousStackLimit),
- StackZeroBits,
- StackReserve,
- MEM_RESERVE | MEM_COMMIT,
- PAGE_READWRITE
- );
-
- /* failure */
- if(!NT_SUCCESS(nErrCode)) goto l_Fail;
-
- /* store the highest (first) address of the stack */
- InitialTeb->PreviousStackBase =
- (PUCHAR)(InitialTeb->PreviousStackLimit) + *StackReserve;
-
- *StackCommit = *StackReserve;
- }
- /* expandable stack */
- else
- {
- ULONG_PTR nGuardSize = PAGE_SIZE;
- PVOID pGuardBase;
-
- DPRINT("Expandable stack\n");
-
- InitialTeb->PreviousStackBase = NULL;
- InitialTeb->PreviousStackLimit = NULL;
-
- InitialTeb->AllocatedStackBase = NULL;
-
- /* reserve the stack */
- nErrCode = NtAllocateVirtualMemory
- (
- ProcessHandle,
- &(InitialTeb->AllocatedStackBase),
- StackZeroBits,
- StackReserve,
- MEM_RESERVE,
- PAGE_READWRITE
- );
-
- /* failure */
- if(!NT_SUCCESS(nErrCode)) goto l_Fail;
-
- DPRINT("Reserved %08X bytes\n", *StackReserve);
-
- /* expandable stack base - the highest address of the stack */
- InitialTeb->StackBase =
- (PUCHAR)(InitialTeb->AllocatedStackBase) + *StackReserve;
-
- /* expandable stack limit - the lowest committed address of the stack */
- InitialTeb->StackLimit =
- (PUCHAR)(InitialTeb->StackBase) - *StackCommit;
-
- DPRINT("Stack commit %p\n", InitialTeb->StackBase);
- DPRINT("Stack commit max %p\n", InitialTeb->StackLimit);
- DPRINT("Stack reserved %p\n", InitialTeb->AllocatedStackBase);
-
- /* commit as much stack as requested */
- nErrCode = NtAllocateVirtualMemory
- (
- ProcessHandle,
- &(InitialTeb->StackLimit),
- 0,
- StackCommit,
- MEM_COMMIT,
- PAGE_READWRITE
- );
-
- /* failure */
- if(!NT_SUCCESS(nErrCode)) goto l_Cleanup;
-
- ASSERT((*StackReserve - *StackCommit) >= PAGE_SIZE);
- ASSERT((*StackReserve - *StackCommit) % PAGE_SIZE == 0);
-
- pGuardBase = (PUCHAR)(InitialTeb->StackLimit) - PAGE_SIZE;
-
- DPRINT("Guard base %p\n", InitialTeb->StackBase);
-
- /* set up the guard page */
- nErrCode = NtAllocateVirtualMemory
- (
- ProcessHandle,
- &pGuardBase,
- 0,
- &nGuardSize,
- MEM_COMMIT,
- PAGE_READWRITE | PAGE_GUARD
- );
-
- /* failure */
- if(!NT_SUCCESS(nErrCode)) goto l_Cleanup;
-
- DPRINT("Guard base %p\n", InitialTeb->StackBase);
- }
-
-
- /* success */
- return STATUS_SUCCESS;
-
- /* deallocate the stack */
-l_Cleanup:
- RtlRosDeleteStack(ProcessHandle, InitialTeb);
-
- /* failure */
-l_Fail:
- ASSERT(!NT_SUCCESS(nErrCode));
- return nErrCode;
-}
-
-NTSTATUS NTAPI RtlRosDeleteStack
-(
- IN HANDLE ProcessHandle,
- IN PINITIAL_TEB InitialTeb
-)
-{
- PVOID pStackLowest = NULL;
- ULONG_PTR nSize;
-
- if(InitialTeb->StackLimit)
- pStackLowest = InitialTeb->PreviousStackLimit;
- else if(InitialTeb->AllocatedStackBase)
- pStackLowest = InitialTeb->AllocatedStackBase;
-
- /* free the stack, if it was allocated */
- if(pStackLowest != NULL)
- return NtFreeVirtualMemory(ProcessHandle, &pStackLowest, &nSize, MEM_RELEASE);
-
- return STATUS_SUCCESS;
-}
-
-NTSTATUS NTAPI RtlRosFreeUserThreadStack
-(
- IN HANDLE ProcessHandle,
- IN HANDLE ThreadHandle
-)
-{
- NTSTATUS nErrCode;
- ULONG nSize = 0;
- PVOID pStackBase;
-
- if(ThreadHandle == NtCurrentThread())
- pStackBase = NtCurrentTeb()->DeallocationStack;
- else
- {
- THREAD_BASIC_INFORMATION tbiInfo;
- ULONG nDummy;
-
- /* query basic information about the thread */
- nErrCode = NtQueryInformationThread
- (
- ThreadHandle,
- ThreadBasicInformation,
- &tbiInfo,
- sizeof(tbiInfo),
- NULL
- );
-
- /* failure */
- if(!NT_SUCCESS(nErrCode)) return nErrCode;
- if(tbiInfo.TebBaseAddress == NULL) return STATUS_ACCESS_VIOLATION;
-
- /* read the base address of the stack to be deallocated */
- nErrCode = NtReadVirtualMemory
- (
- ProcessHandle,
- &((PTEB)tbiInfo.TebBaseAddress)->DeallocationStack,
- &pStackBase,
- sizeof(pStackBase),
- &nDummy
- );
-
- /* failure */
- if(!NT_SUCCESS(nErrCode)) return nErrCode;
- if(pStackBase == NULL) return STATUS_ACCESS_VIOLATION;
- }
-
- /* deallocate the stack */
- nErrCode = NtFreeVirtualMemory(ProcessHandle, &pStackBase, &nSize, MEM_RELEASE);
-
- return nErrCode;
-}
-
-NTSTATUS NTAPI RtlpRosGetStackLimits
-(
- IN PINITIAL_TEB InitialTeb,
- OUT PVOID * StackBase,
- OUT PVOID * StackLimit
-)
-{
- /* fixed-size stack */
- if(InitialTeb->PreviousStackBase && InitialTeb->PreviousStackLimit)
- {
- *StackBase = InitialTeb->PreviousStackBase;
- *StackLimit = InitialTeb->PreviousStackLimit;
- }
- /* expandable stack */
- else if(InitialTeb->StackBase && InitialTeb->StackLimit)
- {
- *StackBase = InitialTeb->StackBase;
- *StackLimit = InitialTeb->StackLimit;
- }
- /* can't determine the type of stack: failure */
- else
- {
- DPRINT("Invalid user-mode stack\n");
- return STATUS_BAD_INITIAL_STACK;
- }
-
- /* valid stack */
- return STATUS_SUCCESS;
-}
-
-/* EOF */
-/* $Id$
- *
- * FILE: ntoskrnl/rtl/qsort.c
- * NOTE: Adapted from CygWin newlib 2000-03-12.
- */
-/*
-FUNCTION
-<<qsort>>---sort an array
-
-INDEX
- qsort
-
-ANSI_SYNOPSIS
- #include <stdlib.h>
- void qsort(void *<[base]>, size_t <[nmemb]>, size_t <[size]>,
- int (*<[compar]>)(const void *, const void *) );
-
-TRAD_SYNOPSIS
- #include <stdlib.h>
- qsort(<[base]>, <[nmemb]>, <[size]>, <[compar]> )
- char *<[base]>;
- size_t <[nmemb]>;
- size_t <[size]>;
- int (*<[compar]>)();
-
-DESCRIPTION
-<<qsort>> sorts an array (beginning at <[base]>) of <[nmemb]> objects.
-<[size]> describes the size of each element of the array.
-
-You must supply a pointer to a comparison function, using the argument
-shown as <[compar]>. (This permits sorting objects of unknown
-properties.) Define the comparison function to accept two arguments,
-each a pointer to an element of the array starting at <[base]>. The
-result of <<(*<[compar]>)>> must be negative if the first argument is
-less than the second, zero if the two arguments match, and positive if
-the first argument is greater than the second (where ``less than'' and
-``greater than'' refer to whatever arbitrary ordering is appropriate).
-
-The array is sorted in place; that is, when <<qsort>> returns, the
-array elements beginning at <[base]> have been reordered.
-
-RETURNS
-<<qsort>> does not return a result.
-
-PORTABILITY
-<<qsort>> is required by ANSI (without specifying the sorting algorithm).
-*/
-
-/*-
- * Copyright (c) 1992, 1993
- * The Regents of the University of California. 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, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
- */
-
-#ifndef __GNUC__
-#define inline
-#endif
-
-/* FIXME: these types should be from the default includes */
-
-typedef int (* _pfunccmp_t) (char *, char *);
-typedef int size_t;
-
-#define min(a,b) ((a)<(b)?(a):(b))
-
-/*
- * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
- */
-#define swapcode(TYPE, parmi, parmj, n) { \
- long i = (n) / sizeof (TYPE); \
- register TYPE *pi = (TYPE *) (parmi); \
- register TYPE *pj = (TYPE *) (parmj); \
- do { \
- register TYPE t = *pi; \
- *pi++ = *pj; \
- *pj++ = t; \
- } while (--i > 0); \
-}
-
-#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
- es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
-
-static inline void
-swapfunc (
- char * a,
- char * b,
- int n,
- int swaptype
- )
-{
- if(swaptype <= 1)
- swapcode(long, a, b, n)
- else
- swapcode(char, a, b, n)
-}
-
-#define swap(a, b) \
- if (swaptype == 0) { \
- long t = *(long *)(a); \
- *(long *)(a) = *(long *)(b); \
- *(long *)(b) = t; \
- } else \
- swapfunc(a, b, es, swaptype)
-
-#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
-
-static inline char *
-med3 (
- char * a,
- char * b,
- char * c,
- _pfunccmp_t cmp
- )
-{
- return cmp(a, b) < 0 ?
- (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))
- :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
-}
-
-
-/* EXPORTED */
-void
-qsort (
- void * a,
- size_t n,
- size_t es,
- _pfunccmp_t cmp
- )
-{
- char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
- int d, r, swaptype, swap_cnt;
-
-loop: SWAPINIT(a, es);
- swap_cnt = 0;
- if (n < 7)
- {
- for ( pm = (char *) a + es;
- pm < (char *) a + n * es;
- pm += es
- )
- {
- for ( pl = pm;
- pl > (char *) a && cmp(pl - es, pl) > 0;
- pl -= es
- )
- {
- swap(pl, pl - es);
- }
- }
- return;
- }
- pm = (char *) a + (n / 2) * es;
- if (n > 7)
- {
- pl = (char *) a;
- pn = (char *) a + (n - 1) * es;
- if (n > 40)
- {
- d = (n / 8) * es;
- pl = med3(pl, pl + d, pl + 2 * d, cmp);
- pm = med3(pm - d, pm, pm + d, cmp);
- pn = med3(pn - 2 * d, pn - d, pn, cmp);
- }
- pm = med3(pl, pm, pn, cmp);
- }
- swap(a, pm);
- pa = pb = (char *) a + es;
-
- pc = pd = (char *) a + (n - 1) * es;
- for (;;)
- {
- while (pb <= pc && (r = cmp(pb, a)) <= 0)
- {
- if (r == 0)
- {
- swap_cnt = 1;
- swap(pa, pb);
- pa += es;
- }
- pb += es;
- }
- while (pb <= pc && (r = cmp(pc, a)) >= 0)
- {
- if (r == 0)
- {
- swap_cnt = 1;
- swap(pc, pd);
- pd -= es;
- }
- pc -= es;
- }
- if (pb > pc)
- {
- break;
- }
- swap(pb, pc);
- swap_cnt = 1;
- pb += es;
- pc -= es;
- }
- if (swap_cnt == 0) /* Switch to insertion sort */
- {
- for ( pm = (char *) a + es;
- pm < (char *) a + n * es;
- pm += es
- )
- {
- for ( pl = pm;
- pl > (char *) a && cmp(pl - es, pl) > 0;
- pl -= es
- )
- {
- swap(pl, pl - es);
- }
- }
- return;
- }
-
- pn = (char *) a + n * es;
- r = min(pa - (char *)a, pb - pa);
- vecswap(a, pb - r, r);
- r = min(pd - pc, pn - pd - es);
- vecswap(pb, pn - r, r);
- if ((r = pb - pa) > es)
- {
- qsort(a, r / es, es, cmp);
- }
- if ((r = pd - pc) > es)
- {
- /* Iterate rather than recurse to save stack space */
- a = pn - r;
- n = r / es;
- goto loop;
- }
-/* qsort(pn - r, r / es, es, cmp);*/
-}
-
-
-/* EOF */
+/* $Id: qsort.c 12852 2005-01-06 13:58:04Z mf $\r
+ * \r
+ * FILE: ntoskrnl/rtl/qsort.c\r
+ * NOTE: Adapted from CygWin newlib 2000-03-12.\r
+ */\r
+/*\r
+FUNCTION\r
+<<qsort>>---sort an array\r
+\r
+INDEX\r
+ qsort\r
+\r
+ANSI_SYNOPSIS\r
+ #include <stdlib.h>\r
+ void qsort(void *<[base]>, size_t <[nmemb]>, size_t <[size]>,\r
+ int (*<[compar]>)(const void *, const void *) );\r
+\r
+TRAD_SYNOPSIS\r
+ #include <stdlib.h>\r
+ qsort(<[base]>, <[nmemb]>, <[size]>, <[compar]> )\r
+ char *<[base]>;\r
+ size_t <[nmemb]>;\r
+ size_t <[size]>;\r
+ int (*<[compar]>)();\r
+\r
+DESCRIPTION\r
+<<qsort>> sorts an array (beginning at <[base]>) of <[nmemb]> objects.\r
+<[size]> describes the size of each element of the array.\r
+\r
+You must supply a pointer to a comparison function, using the argument\r
+shown as <[compar]>. (This permits sorting objects of unknown\r
+properties.) Define the comparison function to accept two arguments,\r
+each a pointer to an element of the array starting at <[base]>. The\r
+result of <<(*<[compar]>)>> must be negative if the first argument is\r
+less than the second, zero if the two arguments match, and positive if\r
+the first argument is greater than the second (where ``less than'' and\r
+``greater than'' refer to whatever arbitrary ordering is appropriate).\r
+\r
+The array is sorted in place; that is, when <<qsort>> returns, the\r
+array elements beginning at <[base]> have been reordered.\r
+\r
+RETURNS\r
+<<qsort>> does not return a result.\r
+\r
+PORTABILITY\r
+<<qsort>> is required by ANSI (without specifying the sorting algorithm).\r
+*/\r
+\r
+/*-\r
+ * Copyright (c) 1992, 1993\r
+ * The Regents of the University of California. All rights reserved.\r
+ *\r
+ * Redistribution and use in source and binary forms, with or without\r
+ * modification, are permitted provided that the following conditions\r
+ * are met:\r
+ * 1. Redistributions of source code must retain the above copyright\r
+ * notice, this list of conditions and the following disclaimer.\r
+ * 2. Redistributions in binary form must reproduce the above copyright\r
+ * notice, this list of conditions and the following disclaimer in the\r
+ * documentation and/or other materials provided with the distribution.\r
+ * 3. All advertising materials mentioning features or use of this software\r
+ * must display the following acknowledgement:\r
+ * This product includes software developed by the University of\r
+ * California, Berkeley and its contributors.\r
+ * 4. Neither the name of the University nor the names of its contributors\r
+ * may be used to endorse or promote products derived from this software\r
+ * without specific prior written permission.\r
+ *\r
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\r
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\r
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\r
+ * SUCH DAMAGE.\r
+ */\r
+\r
+#ifndef __GNUC__\r
+#define inline\r
+#endif\r
+\r
+/* FIXME: these types should be from the default includes */\r
+\r
+typedef int (* _pfunccmp_t) (char *, char *);\r
+typedef int size_t;\r
+\r
+#define min(a,b) ((a)<(b)?(a):(b))\r
+\r
+/*\r
+ * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".\r
+ */\r
+#define swapcode(TYPE, parmi, parmj, n) { \\r
+ long i = (n) / sizeof (TYPE); \\r
+ register TYPE *pi = (TYPE *) (parmi); \\r
+ register TYPE *pj = (TYPE *) (parmj); \\r
+ do { \\r
+ register TYPE t = *pi; \\r
+ *pi++ = *pj; \\r
+ *pj++ = t; \\r
+ } while (--i > 0); \\r
+}\r
+\r
+#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \\r
+ es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;\r
+\r
+static inline void\r
+swapfunc (\r
+ char * a,\r
+ char * b,\r
+ int n,\r
+ int swaptype\r
+ )\r
+{\r
+ if(swaptype <= 1) \r
+ swapcode(long, a, b, n)\r
+ else\r
+ swapcode(char, a, b, n)\r
+}\r
+\r
+#define swap(a, b) \\r
+ if (swaptype == 0) { \\r
+ long t = *(long *)(a); \\r
+ *(long *)(a) = *(long *)(b); \\r
+ *(long *)(b) = t; \\r
+ } else \\r
+ swapfunc(a, b, es, swaptype)\r
+\r
+#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)\r
+\r
+static inline char *\r
+med3 (\r
+ char * a,\r
+ char * b,\r
+ char * c,\r
+ _pfunccmp_t cmp\r
+ )\r
+{\r
+ return cmp(a, b) < 0 ?\r
+ (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ))\r
+ :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));\r
+}\r
+\r
+\r
+/* EXPORTED */\r
+void\r
+qsort (\r
+ void * a,\r
+ size_t n,\r
+ size_t es,\r
+ _pfunccmp_t cmp\r
+ )\r
+{\r
+ char *pa, *pb, *pc, *pd, *pl, *pm, *pn;\r
+ int d, r, swaptype, swap_cnt;\r
+\r
+loop: SWAPINIT(a, es);\r
+ swap_cnt = 0;\r
+ if (n < 7)\r
+ {\r
+ for ( pm = (char *) a + es;\r
+ pm < (char *) a + n * es;\r
+ pm += es\r
+ )\r
+ {\r
+ for ( pl = pm;\r
+ pl > (char *) a && cmp(pl - es, pl) > 0;\r
+ pl -= es\r
+ )\r
+ {\r
+ swap(pl, pl - es);\r
+ }\r
+ }\r
+ return;\r
+ }\r
+ pm = (char *) a + (n / 2) * es;\r
+ if (n > 7)\r
+ {\r
+ pl = (char *) a;\r
+ pn = (char *) a + (n - 1) * es;\r
+ if (n > 40)\r
+ {\r
+ d = (n / 8) * es;\r
+ pl = med3(pl, pl + d, pl + 2 * d, cmp);\r
+ pm = med3(pm - d, pm, pm + d, cmp);\r
+ pn = med3(pn - 2 * d, pn - d, pn, cmp);\r
+ }\r
+ pm = med3(pl, pm, pn, cmp);\r
+ }\r
+ swap(a, pm);\r
+ pa = pb = (char *) a + es;\r
+\r
+ pc = pd = (char *) a + (n - 1) * es;\r
+ for (;;)\r
+ {\r
+ while (pb <= pc && (r = cmp(pb, a)) <= 0)\r
+ {\r
+ if (r == 0)\r
+ {\r
+ swap_cnt = 1;\r
+ swap(pa, pb);\r
+ pa += es;\r
+ }\r
+ pb += es;\r
+ }\r
+ while (pb <= pc && (r = cmp(pc, a)) >= 0)\r
+ {\r
+ if (r == 0)\r
+ {\r
+ swap_cnt = 1;\r
+ swap(pc, pd);\r
+ pd -= es;\r
+ }\r
+ pc -= es;\r
+ }\r
+ if (pb > pc)\r
+ {\r
+ break;\r
+ }\r
+ swap(pb, pc);\r
+ swap_cnt = 1;\r
+ pb += es;\r
+ pc -= es;\r
+ }\r
+ if (swap_cnt == 0) /* Switch to insertion sort */\r
+ {\r
+ for ( pm = (char *) a + es;\r
+ pm < (char *) a + n * es;\r
+ pm += es\r
+ )\r
+ {\r
+ for ( pl = pm;\r
+ pl > (char *) a && cmp(pl - es, pl) > 0; \r
+ pl -= es\r
+ )\r
+ {\r
+ swap(pl, pl - es);\r
+ }\r
+ }\r
+ return;\r
+ }\r
+\r
+ pn = (char *) a + n * es;\r
+ r = min(pa - (char *)a, pb - pa);\r
+ vecswap(a, pb - r, r);\r
+ r = min(pd - pc, pn - pd - es);\r
+ vecswap(pb, pn - r, r);\r
+ if ((r = pb - pa) > es)\r
+ {\r
+ qsort(a, r / es, es, cmp);\r
+ }\r
+ if ((r = pd - pc) > es)\r
+ { \r
+ /* Iterate rather than recurse to save stack space */\r
+ a = pn - r;\r
+ n = r / es;\r
+ goto loop;\r
+ }\r
+/* qsort(pn - r, r / es, es, cmp);*/\r
+}\r
+\r
+\r
+/* EOF */\r
<file>nls.c</file>
<file>ppb.c</file>
<file>process.c</file>
+ <file>qsort.c</file>
<file>random.c</file>
<file>registry.c</file>
<file>sd.c</file>
<library>wine</library>
<library>ntdll</library>
<library>gdi32</library>
- <library>rosrtl</library>
<library>kernel32</library>
<library>advapi32</library>
<directory name="include">
<library>kjs</library>
<library>pseh</library>
<library>rtl</library>
- <library>rosrtl</library>
<library>rossym</library>
<library>string</library>
<library>wdmguid</library>
<library>regtests</library>
<library>win32k_base</library>
<library>pseh</library>
- <library>rosrtl</library>
<directory name="tests">
<file>DIB_24BPP_ColorFill-performance.c</file>
</directory>
<importlibrary definition="win32k.def" />
<library>win32k_base</library>
<library>pseh</library>
- <library>rosrtl</library>
<library>ntoskrnl</library>
<library>hal</library>
<library>freetype</library>