- 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 <roscfg.h>
#include <limits.h> #include <limits.h>
#include <ddk/ntddk.h> #include <ddk/ntddk.h>
#include <rosrtl/recmutex.h> #include <../recmutex/recmutex.h>
#include <roscfg.h> #include <roscfg.h>
#include <tcpip.h> #include <tcpip.h>
#include <loopback.h> #include <loopback.h>

View file

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

View file

@ -8,7 +8,6 @@
<library>ip</library> <library>ip</library>
<library>oskittcp</library> <library>oskittcp</library>
<library>ndis</library> <library>ndis</library>
<library>rosrtl</library>
<library>pseh</library> <library>pseh</library>
<library>ntoskrnl</library> <library>ntoskrnl</library>
<library>hal</library> <library>hal</library>
@ -18,6 +17,9 @@
<directory name="datalink"> <directory name="datalink">
<file>lan.c</file> <file>lan.c</file>
</directory> </directory>
<directory name="recmutex">
<file>recmutex.c</file>
</directory>
<directory name="tcpip"> <directory name="tcpip">
<file>buffer.c</file> <file>buffer.c</file>
<file>bug.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"> <directory name="riched20">
<xi:include href="riched20/riched20.xml" /> <xi:include href="riched20/riched20.xml" />
</directory> </directory>
<directory name="rosrtl">
<xi:include href="rosrtl/rosrtl.xml" />
</directory>
<directory name="rossym"> <directory name="rossym">
<xi:include href="rossym/rossym.xml" /> <xi:include href="rossym/rossym.xml" />
</directory> </directory>

View file

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

View file

@ -7,7 +7,6 @@
<define name="WINVER">0x0600</define> <define name="WINVER">0x0600</define>
<define name="_WIN32_WINNT">0x0501</define> <define name="_WIN32_WINNT">0x0501</define>
<library>ntdll</library> <library>ntdll</library>
<library>rosrtl</library>
<library>kernel32</library> <library>kernel32</library>
<library>advapi32</library> <library>advapi32</library>
<directory name="include"> <directory name="include">

View file

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

View file

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

View file

@ -8,7 +8,6 @@
<define name="_WIN32_WINNT">0x0502</define> <define name="_WIN32_WINNT">0x0502</define>
<define name="_NTOSKRNL_" /> <define name="_NTOSKRNL_" />
<library>rtl</library> <library>rtl</library>
<library>rosrtl</library>
<library>intrlck</library> <library>intrlck</library>
<library>string</library> <library>string</library>
<linkerflag>-lgcc</linkerflag> <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$ /* $Id: qsort.c 12852 2005-01-06 13:58:04Z mf $
* *
* FILE: ntoskrnl/rtl/qsort.c * FILE: ntoskrnl/rtl/qsort.c
* NOTE: Adapted from CygWin newlib 2000-03-12. * NOTE: Adapted from CygWin newlib 2000-03-12.
*/ */
/* /*
FUNCTION FUNCTION
<<qsort>>---sort an array <<qsort>>---sort an array
INDEX INDEX
qsort qsort
ANSI_SYNOPSIS ANSI_SYNOPSIS
#include <stdlib.h> #include <stdlib.h>
void qsort(void *<[base]>, size_t <[nmemb]>, size_t <[size]>, void qsort(void *<[base]>, size_t <[nmemb]>, size_t <[size]>,
int (*<[compar]>)(const void *, const void *) ); int (*<[compar]>)(const void *, const void *) );
TRAD_SYNOPSIS TRAD_SYNOPSIS
#include <stdlib.h> #include <stdlib.h>
qsort(<[base]>, <[nmemb]>, <[size]>, <[compar]> ) qsort(<[base]>, <[nmemb]>, <[size]>, <[compar]> )
char *<[base]>; char *<[base]>;
size_t <[nmemb]>; size_t <[nmemb]>;
size_t <[size]>; size_t <[size]>;
int (*<[compar]>)(); int (*<[compar]>)();
DESCRIPTION DESCRIPTION
<<qsort>> sorts an array (beginning at <[base]>) of <[nmemb]> objects. <<qsort>> sorts an array (beginning at <[base]>) of <[nmemb]> objects.
<[size]> describes the size of each element of the array. <[size]> describes the size of each element of the array.
You must supply a pointer to a comparison function, using the argument You must supply a pointer to a comparison function, using the argument
shown as <[compar]>. (This permits sorting objects of unknown shown as <[compar]>. (This permits sorting objects of unknown
properties.) Define the comparison function to accept two arguments, properties.) Define the comparison function to accept two arguments,
each a pointer to an element of the array starting at <[base]>. The each a pointer to an element of the array starting at <[base]>. The
result of <<(*<[compar]>)>> must be negative if the first argument is result of <<(*<[compar]>)>> must be negative if the first argument is
less than the second, zero if the two arguments match, and positive if 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 the first argument is greater than the second (where ``less than'' and
``greater than'' refer to whatever arbitrary ordering is appropriate). ``greater than'' refer to whatever arbitrary ordering is appropriate).
The array is sorted in place; that is, when <<qsort>> returns, the The array is sorted in place; that is, when <<qsort>> returns, the
array elements beginning at <[base]> have been reordered. array elements beginning at <[base]> have been reordered.
RETURNS RETURNS
<<qsort>> does not return a result. <<qsort>> does not return a result.
PORTABILITY PORTABILITY
<<qsort>> is required by ANSI (without specifying the sorting algorithm). <<qsort>> is required by ANSI (without specifying the sorting algorithm).
*/ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved. * The Regents of the University of California. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* 1. Redistributions of source code must retain the above copyright * 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement: * must display the following acknowledgement:
* This product includes software developed by the University of * This product includes software developed by the University of
* California, Berkeley and its contributors. * California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * 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 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#ifndef __GNUC__ #ifndef __GNUC__
#define inline #define inline
#endif #endif
/* FIXME: these types should be from the default includes */ /* FIXME: these types should be from the default includes */
typedef int (* _pfunccmp_t) (char *, char *); typedef int (* _pfunccmp_t) (char *, char *);
typedef int size_t; typedef int size_t;
#define min(a,b) ((a)<(b)?(a):(b)) #define min(a,b) ((a)<(b)?(a):(b))
/* /*
* Qsort routine from Bentley & McIlroy's "Engineering a Sort Function". * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
*/ */
#define swapcode(TYPE, parmi, parmj, n) { \ #define swapcode(TYPE, parmi, parmj, n) { \
long i = (n) / sizeof (TYPE); \ long i = (n) / sizeof (TYPE); \
register TYPE *pi = (TYPE *) (parmi); \ register TYPE *pi = (TYPE *) (parmi); \
register TYPE *pj = (TYPE *) (parmj); \ register TYPE *pj = (TYPE *) (parmj); \
do { \ do { \
register TYPE t = *pi; \ register TYPE t = *pi; \
*pi++ = *pj; \ *pi++ = *pj; \
*pj++ = t; \ *pj++ = t; \
} while (--i > 0); \ } while (--i > 0); \
} }
#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ #define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
static inline void static inline void
swapfunc ( swapfunc (
char * a, char * a,
char * b, char * b,
int n, int n,
int swaptype int swaptype
) )
{ {
if(swaptype <= 1) if(swaptype <= 1)
swapcode(long, a, b, n) swapcode(long, a, b, n)
else else
swapcode(char, a, b, n) swapcode(char, a, b, n)
} }
#define swap(a, b) \ #define swap(a, b) \
if (swaptype == 0) { \ if (swaptype == 0) { \
long t = *(long *)(a); \ long t = *(long *)(a); \
*(long *)(a) = *(long *)(b); \ *(long *)(a) = *(long *)(b); \
*(long *)(b) = t; \ *(long *)(b) = t; \
} else \ } else \
swapfunc(a, b, es, swaptype) swapfunc(a, b, es, swaptype)
#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) #define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
static inline char * static inline char *
med3 ( med3 (
char * a, char * a,
char * b, char * b,
char * c, char * c,
_pfunccmp_t cmp _pfunccmp_t cmp
) )
{ {
return cmp(a, b) < 0 ? 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 ? c : a ))
:(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c )); :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ));
} }
/* EXPORTED */ /* EXPORTED */
void void
qsort ( qsort (
void * a, void * a,
size_t n, size_t n,
size_t es, size_t es,
_pfunccmp_t cmp _pfunccmp_t cmp
) )
{ {
char *pa, *pb, *pc, *pd, *pl, *pm, *pn; char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
int d, r, swaptype, swap_cnt; int d, r, swaptype, swap_cnt;
loop: SWAPINIT(a, es); loop: SWAPINIT(a, es);
swap_cnt = 0; swap_cnt = 0;
if (n < 7) if (n < 7)
{ {
for ( pm = (char *) a + es; for ( pm = (char *) a + es;
pm < (char *) a + n * es; pm < (char *) a + n * es;
pm += es pm += es
) )
{ {
for ( pl = pm; for ( pl = pm;
pl > (char *) a && cmp(pl - es, pl) > 0; pl > (char *) a && cmp(pl - es, pl) > 0;
pl -= es pl -= es
) )
{ {
swap(pl, pl - es); swap(pl, pl - es);
} }
} }
return; return;
} }
pm = (char *) a + (n / 2) * es; pm = (char *) a + (n / 2) * es;
if (n > 7) if (n > 7)
{ {
pl = (char *) a; pl = (char *) a;
pn = (char *) a + (n - 1) * es; pn = (char *) a + (n - 1) * es;
if (n > 40) if (n > 40)
{ {
d = (n / 8) * es; d = (n / 8) * es;
pl = med3(pl, pl + d, pl + 2 * d, cmp); pl = med3(pl, pl + d, pl + 2 * d, cmp);
pm = med3(pm - d, pm, pm + d, cmp); pm = med3(pm - d, pm, pm + d, cmp);
pn = med3(pn - 2 * d, pn - d, pn, cmp); pn = med3(pn - 2 * d, pn - d, pn, cmp);
} }
pm = med3(pl, pm, pn, cmp); pm = med3(pl, pm, pn, cmp);
} }
swap(a, pm); swap(a, pm);
pa = pb = (char *) a + es; pa = pb = (char *) a + es;
pc = pd = (char *) a + (n - 1) * es; pc = pd = (char *) a + (n - 1) * es;
for (;;) for (;;)
{ {
while (pb <= pc && (r = cmp(pb, a)) <= 0) while (pb <= pc && (r = cmp(pb, a)) <= 0)
{ {
if (r == 0) if (r == 0)
{ {
swap_cnt = 1; swap_cnt = 1;
swap(pa, pb); swap(pa, pb);
pa += es; pa += es;
} }
pb += es; pb += es;
} }
while (pb <= pc && (r = cmp(pc, a)) >= 0) while (pb <= pc && (r = cmp(pc, a)) >= 0)
{ {
if (r == 0) if (r == 0)
{ {
swap_cnt = 1; swap_cnt = 1;
swap(pc, pd); swap(pc, pd);
pd -= es; pd -= es;
} }
pc -= es; pc -= es;
} }
if (pb > pc) if (pb > pc)
{ {
break; break;
} }
swap(pb, pc); swap(pb, pc);
swap_cnt = 1; swap_cnt = 1;
pb += es; pb += es;
pc -= es; pc -= es;
} }
if (swap_cnt == 0) /* Switch to insertion sort */ if (swap_cnt == 0) /* Switch to insertion sort */
{ {
for ( pm = (char *) a + es; for ( pm = (char *) a + es;
pm < (char *) a + n * es; pm < (char *) a + n * es;
pm += es pm += es
) )
{ {
for ( pl = pm; for ( pl = pm;
pl > (char *) a && cmp(pl - es, pl) > 0; pl > (char *) a && cmp(pl - es, pl) > 0;
pl -= es pl -= es
) )
{ {
swap(pl, pl - es); swap(pl, pl - es);
} }
} }
return; return;
} }
pn = (char *) a + n * es; pn = (char *) a + n * es;
r = min(pa - (char *)a, pb - pa); r = min(pa - (char *)a, pb - pa);
vecswap(a, pb - r, r); vecswap(a, pb - r, r);
r = min(pd - pc, pn - pd - es); r = min(pd - pc, pn - pd - es);
vecswap(pb, pn - r, r); vecswap(pb, pn - r, r);
if ((r = pb - pa) > es) if ((r = pb - pa) > es)
{ {
qsort(a, r / es, es, cmp); qsort(a, r / es, es, cmp);
} }
if ((r = pd - pc) > es) if ((r = pd - pc) > es)
{ {
/* Iterate rather than recurse to save stack space */ /* Iterate rather than recurse to save stack space */
a = pn - r; a = pn - r;
n = r / es; n = r / es;
goto loop; goto loop;
} }
/* qsort(pn - r, r / es, es, cmp);*/ /* qsort(pn - r, r / es, es, cmp);*/
} }
/* EOF */ /* EOF */

View file

@ -37,6 +37,7 @@
<file>nls.c</file> <file>nls.c</file>
<file>ppb.c</file> <file>ppb.c</file>
<file>process.c</file> <file>process.c</file>
<file>qsort.c</file>
<file>random.c</file> <file>random.c</file>
<file>registry.c</file> <file>registry.c</file>
<file>sd.c</file> <file>sd.c</file>

View file

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

View file

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

View file

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

View file

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