- Remove ROSRTL. The era is over. Thanks to Filip for his help during the last month.

svn path=/trunk/; revision=16731
This commit is contained in:
Alex Ionescu 2005-07-26 04:52:11 +00:00
parent 1e8c8e3fe6
commit f3622d33aa
32 changed files with 272 additions and 1904 deletions

View file

@ -1,7 +1,7 @@
#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>

View file

@ -1,5 +1,5 @@
#include <ddk/ntddk.h>
#include <rosrtl/recmutex.h>
#include "recmutex.h"
VOID RecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ) {
RtlZeroMemory( RecMutex, sizeof(*RecMutex) );

View file

@ -8,7 +8,6 @@
<library>ip</library>
<library>oskittcp</library>
<library>ndis</library>
<library>rosrtl</library>
<library>pseh</library>
<library>ntoskrnl</library>
<library>hal</library>
@ -18,6 +17,9 @@
<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>

View file

@ -1,108 +0,0 @@
/* $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 */

View file

@ -214,9 +214,6 @@
<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>

View file

@ -7,7 +7,6 @@
<define name="ADNS_JGAA_WIN32" />
<define name="__USE_W32API" />
<library>adns</library>
<library>rosrtl</library>
<library>ntdll</library>
<library>kernel32</library>
<library>user32</library>

View file

@ -7,7 +7,6 @@
<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">

View file

@ -118,7 +118,6 @@
<define name="WINVER">0x0500</define>
<library>kernel32_base</library>
<library>pseh</library>
<library>rosrtl</library>
<library>intrlck</library>
<library>ntdll</library>
<linkerflag>-lgcc</linkerflag>

View file

@ -10,7 +10,6 @@
<library>regtests</library>
<library>kernel32_base</library>
<library>pseh</library>
<library>rosrtl</library>
<library>ntdll</library>
<library>msvcrt</library>
<linkerflag>-lgcc</linkerflag>

View file

@ -8,7 +8,6 @@
<define name="_WIN32_WINNT">0x0502</define>
<define name="_NTOSKRNL_" />
<library>rtl</library>
<library>rosrtl</library>
<library>intrlck</library>
<library>string</library>
<linkerflag>-lgcc</linkerflag>

View file

@ -1,100 +0,0 @@
#include <windows.h>
#include <string.h>
/***********************************************************************
* MakeSureDirectoryPathExistsExA
*
* If a dir is at the end and the path ends with a backslash, FileAtEnd
* is ignored. If the path doesn't end with a backslash, FileAtEnd is
* used to determine if the last part of the path is a file name or a
* directory.
*
* Path may be absolute or relative to current dir.
*/
BOOL STDCALL MakeSureDirectoryPathExistsExA(LPCSTR DirPath, BOOL FileAtEnd)
{
char Path[MAX_PATH];
char *SlashPos = Path;
char Slash;
BOOL bRes;
strcpy(Path, DirPath);
while((SlashPos=strpbrk(SlashPos+1,"\\/")))
{
Slash = *SlashPos;
*SlashPos = 0;
bRes = CreateDirectoryA(Path, NULL);
if (bRes == FALSE && GetLastError() != ERROR_ALREADY_EXISTS)
{
return FALSE;
}
*SlashPos = Slash;
if (*(SlashPos+1) == 0) return TRUE;
}
if (!FileAtEnd)
{
bRes = CreateDirectoryA(Path, NULL);
if (bRes == FALSE && GetLastError() != ERROR_ALREADY_EXISTS)
{
return FALSE;
}
}
return TRUE;
}
/***********************************************************************
* MakeSureDirectoryPathExistsExW
*
* If a dir is at the end and the path ends with a backslash, FileAtEnd
* is ignored. If the path doesn't end with a backslash, FileAtEnd is
* used to determine if the last part of the path is a file name or a
* directory.
*
* Path may be absolute or relative to current dir.
*/
BOOL STDCALL MakeSureDirectoryPathExistsExW(LPCWSTR DirPath, BOOL FileAtEnd)
{
WCHAR Path[MAX_PATH];
WCHAR *SlashPos = Path;
WCHAR Slash;
BOOL bRes;
wcscpy(Path, DirPath);
while((SlashPos=wcspbrk(SlashPos+1,L"\\/")))
{
Slash = *SlashPos;
*SlashPos = 0;
bRes = CreateDirectoryW(Path, NULL);
if (bRes == FALSE && GetLastError() != ERROR_ALREADY_EXISTS)
{
return FALSE;
}
*SlashPos = Slash;
if (*(SlashPos+1) == 0) return TRUE;
}
if (!FileAtEnd)
{
bRes = CreateDirectoryW(Path, NULL);
if (bRes == FALSE && GetLastError() != ERROR_ALREADY_EXISTS)
{
return FALSE;
}
}
return TRUE;
}

View file

@ -1,117 +0,0 @@
#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

View file

@ -1,148 +0,0 @@
#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

View file

@ -1,55 +0,0 @@
#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

View file

@ -1,79 +0,0 @@
#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

View file

@ -1,32 +0,0 @@
<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>

View file

@ -1,39 +0,0 @@
#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;
}

View file

@ -1,224 +0,0 @@
#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;
}

View file

@ -1,146 +0,0 @@
/* $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 */

View file

@ -1,40 +0,0 @@
/* $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 */

View file

@ -1,91 +0,0 @@
/* $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 */

View file

@ -1,13 +0,0 @@
.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 */

View file

@ -1,38 +0,0 @@
/* $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 */

View file

@ -1,122 +0,0 @@
#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

View file

@ -1,271 +0,0 @@
/* $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 */

View file

@ -1,266 +1,266 @@
/* $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 $
*
* 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 */

View file

@ -37,6 +37,7 @@
<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>

View file

@ -11,7 +11,6 @@
<library>wine</library>
<library>ntdll</library>
<library>gdi32</library>
<library>rosrtl</library>
<library>kernel32</library>
<library>advapi32</library>
<directory name="include">

View file

@ -14,7 +14,6 @@
<library>kjs</library>
<library>pseh</library>
<library>rtl</library>
<library>rosrtl</library>
<library>rossym</library>
<library>string</library>
<library>wdmguid</library>

View file

@ -14,7 +14,6 @@
<library>regtests</library>
<library>win32k_base</library>
<library>pseh</library>
<library>rosrtl</library>
<directory name="tests">
<file>DIB_24BPP_ColorFill-performance.c</file>
</directory>

View file

@ -132,7 +132,6 @@
<importlibrary definition="win32k.def" />
<library>win32k_base</library>
<library>pseh</library>
<library>rosrtl</library>
<library>ntoskrnl</library>
<library>hal</library>
<library>freetype</library>