Author: ion
Date: Thu Aug 29 20:13:31 2013
New Revision: 59879
URL:
http://svn.reactos.org/svn/reactos?rev=59879&view=rev
Log:
[BASESRV]: The last few APIs were off-by-one due to an unimplmented (in Windows) or
deprecated api.c
[BASESRV]: Implement BaseSrvNlsCreateSection, which is needed by Windows kernel32.dll.
Also implement the delay-loading functionality it needs.
Modified:
trunk/reactos/include/reactos/subsys/win/basemsg.h
trunk/reactos/subsystems/win/basesrv/basesrv.h
trunk/reactos/subsystems/win/basesrv/init.c
trunk/reactos/subsystems/win/basesrv/nls.c
trunk/reactos/subsystems/win32/csrsrv/api.c
Modified: trunk/reactos/include/reactos/subsys/win/basemsg.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/subsys/win…
==============================================================================
--- trunk/reactos/include/reactos/subsys/win/basemsg.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/subsys/win/basemsg.h [iso-8859-1] Thu Aug 29 20:13:31
2013
@@ -46,6 +46,7 @@
BasepNlsUpdateCacheCount,
BasepSetTermsrvClientTimeZone,
BasepSxsCreateActivationContext,
+ BasepUnknown,
BasepRegisterThread,
BasepNlsGetUserInfo,
BasepMaxApiNumber
@@ -260,6 +261,13 @@
UNICODE_STRING TargetPath;
} BASE_DEFINE_DOS_DEVICE, *PBASE_DEFINE_DOS_DEVICE;
+typedef struct
+{
+ HANDLE SectionHandle;
+ ULONG Type;
+ ULONG LocaleId;
+} BASE_NLS_CREATE_SECTION, *PBASE_NLS_CREATE_SECTION;
+
typedef struct _BASE_API_MESSAGE
{
PORT_MESSAGE Header;
@@ -288,6 +296,7 @@
BASE_SOUND_SENTRY SoundSentryRequest;
BASE_REFRESH_INIFILE_MAPPING RefreshIniFileMappingRequest;
BASE_DEFINE_DOS_DEVICE DefineDosDeviceRequest;
+ BASE_NLS_CREATE_SECTION NlsCreateSection;
} Data;
} BASE_API_MESSAGE, *PBASE_API_MESSAGE;
Modified: trunk/reactos/subsystems/win/basesrv/basesrv.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win/basesrv/bas…
==============================================================================
--- trunk/reactos/subsystems/win/basesrv/basesrv.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win/basesrv/basesrv.h [iso-8859-1] Thu Aug 29 20:13:31 2013
@@ -24,6 +24,32 @@
#include <win/basemsg.h>
#include <win/base.h>
+typedef struct _BASESRV_KERNEL_IMPORTS
+{
+ PCHAR FunctionName;
+ PVOID* FunctionPointer;
+} BASESRV_KERNEL_IMPORTS, *PBASESRV_KERNEL_IMPORTS;
+
+/* FIXME: BASENLS.H */
+typedef NTSTATUS(*WINAPI POPEN_DATA_FILE) (HANDLE hFile,
+ PWCHAR FileName
+ );
+
+typedef BOOL(*WINAPI PGET_CP_FILE_NAME_FROM_REGISTRY)(UINT CodePage,
+ LPWSTR FileName,
+ ULONG FileNameSize
+ );
+
+typedef BOOL(*WINAPI PGET_NLS_SECTION_NAME)(UINT CodePage,
+ UINT Base,
+ ULONG Unknown,
+ LPSTR BaseName,
+ LPSTR Result,
+ ULONG ResultSize
+ );
+
+typedef BOOL(*WINAPI PVALIDATE_LOCALE)(IN ULONG LocaleId);
+typedef NTSTATUS(*WINAPI PCREATE_NLS_SECURTY_DESCRIPTOR)(IN PVOID Buffer, IN ULONG
BufferSize, IN ULONG AceType);
/* Globals */
extern HANDLE BaseSrvHeap;
Modified: trunk/reactos/subsystems/win/basesrv/init.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win/basesrv/ini…
==============================================================================
--- trunk/reactos/subsystems/win/basesrv/init.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win/basesrv/init.c [iso-8859-1] Thu Aug 29 20:13:31 2013
@@ -17,6 +17,7 @@
/* GLOBALS ********************************************************************/
HANDLE BaseSrvDllInstance = NULL;
+extern UNICODE_STRING BaseSrvKernel32DllPath;
/* Memory */
HANDLE BaseSrvHeap = NULL; // Our own heap.
@@ -54,6 +55,7 @@
BaseSrvNlsUpdateCacheCount,
BaseSrvSetTermsrvClientTimeZone,
BaseSrvSxsCreateActivationContext,
+ BaseSrvDebugProcess,
BaseSrvRegisterThread,
BaseSrvNlsGetUserInfo,
};
@@ -84,12 +86,13 @@
TRUE, // BaseSrvSoundSentryNotification
TRUE, // BaseSrvRefreshIniFileMapping
TRUE, // BaseSrvDefineDosDevice
- FALSE, // BaseSrvSetTermsrvAppInstallMode
- FALSE, // BaseSrvNlsUpdateCacheCount
- FALSE, // BaseSrvSetTermsrvClientTimeZone
- FALSE, // BaseSrvSxsCreateActivationContext
- FALSE, // BaseSrvRegisterThread
- FALSE, // BaseSrvNlsGetUserInfo
+ TRUE, // BaseSrvSetTermsrvAppInstallMode
+ TRUE, // BaseSrvNlsUpdateCacheCount
+ TRUE, // BaseSrvSetTermsrvClientTimeZone
+ TRUE, // BaseSrvSxsCreateActivationContext
+ TRUE, // BasepDebugProcess
+ TRUE, // BaseSrvRegisterThread
+ TRUE, // BaseSrvNlsGetUserInfo
};
PCHAR BaseServerApiNameTable[BasepMaxApiNumber - BASESRV_FIRST_API_NUMBER] =
@@ -311,6 +314,12 @@
SystemRootString.Buffer);
ASSERT(NT_SUCCESS(Status));
+ /* Create the kernel32 path */
+ wcscat(SystemRootString.Buffer, L"\\kernel32.dll");
+ Status = RtlCreateUnicodeString(&BaseSrvKernel32DllPath,
+ SystemRootString.Buffer);
+ ASSERT(NT_SUCCESS(Status));
+
/* FIXME: Check Session ID */
wcscpy(Buffer, L"\\BaseNamedObjects");
RtlInitUnicodeString(&BnoString, Buffer);
Modified: trunk/reactos/subsystems/win/basesrv/nls.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win/basesrv/nls…
==============================================================================
--- trunk/reactos/subsystems/win/basesrv/nls.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win/basesrv/nls.c [iso-8859-1] Thu Aug 29 20:13:31 2013
@@ -13,6 +13,95 @@
#define NDEBUG
#include <debug.h>
+/* GLOBALS ********************************************************************/
+
+BOOLEAN BaseSrvKernel32DelayLoadComplete;
+HANDLE BaseSrvKernel32DllHandle;
+UNICODE_STRING BaseSrvKernel32DllPath;
+
+POPEN_DATA_FILE pOpenDataFile;
+PVOID /*PGET_DEFAULT_SORTKEY_SIZE */ pGetDefaultSortkeySize;
+PVOID /*PGET_LINGUIST_LANG_SIZE*/ pGetLinguistLangSize;
+PVOID /*PNLS_CONVERT_INTEGER_TO_STRING*/ pNlsConvertIntegerToString;
+PVOID /*PVALIDATE_LCTYPE*/ pValidateLCType;
+PVALIDATE_LOCALE pValidateLocale;
+PGET_NLS_SECTION_NAME pGetNlsSectionName;
+PVOID /*PGET_USER_DEFAULT_LANGID*/ pGetUserDefaultLangID;
+PGET_CP_FILE_NAME_FROM_REGISTRY pGetCPFileNameFromRegistry;
+PCREATE_NLS_SECURTY_DESCRIPTOR pCreateNlsSecurityDescriptor;
+
+BASESRV_KERNEL_IMPORTS BaseSrvKernel32Imports[10] =
+{
+ { "OpenDataFile", (PVOID*) &pOpenDataFile },
+ { "GetDefaultSortkeySize", (PVOID*) &pGetDefaultSortkeySize },
+ { "GetLinguistLangSize", (PVOID*) &pGetLinguistLangSize },
+ { "NlsConvertIntegerToString", (PVOID*) &pNlsConvertIntegerToString },
+ { "ValidateLCType", (PVOID*) &pValidateLCType },
+ { "ValidateLocale", (PVOID*) &pValidateLocale },
+ { "GetNlsSectionName", (PVOID*) &pGetNlsSectionName },
+ { "GetUserDefaultLangID", (PVOID*) &pGetUserDefaultLangID },
+ { "GetCPFileNameFromRegistry", (PVOID*) &pGetCPFileNameFromRegistry },
+ { "CreateNlsSecurityDescriptor", (PVOID*) &pCreateNlsSecurityDescriptor
},
+};
+
+/* FUNCTIONS *****************************************************************/
+
+NTSTATUS
+NTAPI
+BaseSrvDelayLoadKernel32(VOID)
+{
+ NTSTATUS Status;
+ ULONG i;
+ ANSI_STRING ProcedureName;
+
+ /* Only do this once */
+ if (BaseSrvKernel32DelayLoadComplete) return STATUS_SUCCESS;
+
+ /* Loop all imports */
+ for (i = 0; i < RTL_NUMBER_OF(BaseSrvKernel32Imports); i++)
+ {
+ /* Only look them up once */
+ if (!*BaseSrvKernel32Imports[i].FunctionPointer)
+ {
+ /* If we haven't loaded the DLL yet, do it now */
+ if (!BaseSrvKernel32DllHandle)
+ {
+ Status = LdrLoadDll(0,
+ 0,
+ &BaseSrvKernel32DllPath,
+ &BaseSrvKernel32DllHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to load %wZ\n",
&BaseSrvKernel32DllPath);
+ return Status;
+ }
+ }
+
+ /* Get the address of the routine being looked up*/
+ RtlInitAnsiString(&ProcedureName,
BaseSrvKernel32Imports[i].FunctionName);
+ Status = LdrGetProcedureAddress(BaseSrvKernel32DllHandle,
+ &ProcedureName,
+ 0,
+ BaseSrvKernel32Imports[i].FunctionPointer);
+ DPRINT1("NLS: Found %Z at 0x%p\n",
+ &ProcedureName,
+ BaseSrvKernel32Imports[i].FunctionPointer);
+ if (!NT_SUCCESS(Status)) break;
+ }
+ }
+
+ /* Did we find them all? */
+ if (i == RTL_NUMBER_OF(BaseSrvKernel32Imports))
+ {
+ /* Excellent */
+ BaseSrvKernel32DelayLoadComplete = TRUE;
+ return STATUS_SUCCESS;
+ }
+
+ /* Nope, fail */
+ return Status;
+}
+
/* PUBLIC SERVER APIS *********************************************************/
CSR_API(BaseSrvNlsSetUserInfo)
@@ -28,10 +117,147 @@
}
CSR_API(BaseSrvNlsCreateSection)
-
-{
- DPRINT1("%s not yet implemented\n", __FUNCTION__);
- return STATUS_NOT_IMPLEMENTED;
+{
+ NTSTATUS Status;
+ HANDLE SectionHandle, ProcessHandle, FileHandle;
+ ULONG LocaleId;
+ UNICODE_STRING NlsSectionName;
+ PWCHAR NlsFileName;
+ UCHAR SecurityDescriptor[52];
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ PBASE_NLS_CREATE_SECTION NlsMsg =
&((PBASE_API_MESSAGE)ApiMessage)->Data.NlsCreateSection;
+
+ /* Load kernel32 first and import the NLS routines */
+ Status = BaseSrvDelayLoadKernel32();
+ if (!NT_SUCCESS(Status)) return Status;
+
+ /* Assume failure */
+ NlsMsg->SectionHandle = NULL;
+
+ /* Check and validate the locale ID, if one is present */
+ LocaleId = NlsMsg->LocaleId;
+ DPRINT1("NLS: Create Section with LCID: %lx for Type: %d\n", LocaleId,
NlsMsg->Type);
+ if (LocaleId)
+ {
+ if (!pValidateLocale(LocaleId)) return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Check which NLS section is being created */
+ switch (NlsMsg->Type)
+ {
+ /* For each one, set the correct filename and object name */
+ case 1:
+ RtlInitUnicodeString(&NlsSectionName,
L"\\NLS\\NlsSectionUnicode");
+ NlsFileName = L"unicode.nls";
+ break;
+ case 2:
+ RtlInitUnicodeString(&NlsSectionName,
L"\\NLS\\NlsSectionLocale");
+ NlsFileName = L"locale.nls";
+ break;
+ case 3:
+ RtlInitUnicodeString(&NlsSectionName,
L"\\NLS\\NlsSectionCType");
+ NlsFileName = L"ctype.nls";
+ break;
+ case 4:
+ RtlInitUnicodeString(&NlsSectionName,
L"\\NLS\\NlsSectionSortkey");
+ NlsFileName = L"sortkey.nls";
+ break;
+ case 5:
+ RtlInitUnicodeString(&NlsSectionName,
L"\\NLS\\NlsSectionSortTbls");
+ NlsFileName = L"sorttbls.nls";
+ break;
+ case 6:
+ RtlInitUnicodeString(&NlsSectionName,
L"\\NLS\\NlsSectionCP437");
+ NlsFileName = L"c_437.nls";
+ break;
+ case 7:
+ RtlInitUnicodeString(&NlsSectionName,
L"\\NLS\\NlsSectionCP1252");
+ NlsFileName = L"c_1252.nls";
+ break;
+ case 8:
+ RtlInitUnicodeString(&NlsSectionName,
L"\\NLS\\NlsSectionLANG_EXCEPT");
+ NlsFileName = L"l_except.nls";
+ break;
+ case 9:
+ DPRINT1("This type not yet supported\n");
+ return STATUS_NOT_IMPLEMENTED;
+ case 10:
+ DPRINT1("This type not yet supported\n");
+ return STATUS_NOT_IMPLEMENTED;
+ case 11:
+ DPRINT1("This type not yet supported\n");
+ return STATUS_NOT_IMPLEMENTED;
+ case 12:
+ RtlInitUnicodeString(&NlsSectionName,
L"\\NLS\\NlsSectionGeo");
+ NlsFileName = L"geo.nls";
+ break;
+ default:
+ DPRINT1("NLS: Invalid NLS type!\n");
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Open the specified NLS file */
+ Status = pOpenDataFile(&FileHandle, NlsFileName);
+ if (Status != STATUS_SUCCESS)
+ {
+ DPRINT1("NLS: Failed to open file: %lx\n", Status);
+ return Status;
+ }
+
+ /* Create an SD for the section object */
+ Status = pCreateNlsSecurityDescriptor(&SecurityDescriptor,
+ sizeof(SecurityDescriptor),
+ 0x80000000);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NLS: CreateNlsSecurityDescriptor FAILED!: %lx\n", Status);
+ NtClose(FileHandle);
+ return Status;
+ }
+
+ /* Create the section object proper */
+ InitializeObjectAttributes(&ObjectAttributes,
+ &NlsSectionName,
+ OBJ_CASE_INSENSITIVE | OBJ_PERMANENT | OBJ_OPENIF,
+ NULL,
+ &SecurityDescriptor);
+ Status = NtCreateSection(&SectionHandle,
+ SECTION_MAP_READ,
+ &ObjectAttributes,
+ 0,
+ PAGE_READONLY,
+ SEC_COMMIT,
+ FileHandle);
+ NtClose(FileHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NLS: Failed to create section! %lx\n", Status);
+ return Status;
+ }
+
+ /* Open a handle to the calling process */
+ InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
+ Status = NtOpenProcess(&ProcessHandle,
+ PROCESS_DUP_HANDLE,
+ &ObjectAttributes,
+ &ApiMessage->Header.ClientId);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("NLS: Failed to open process! %lx\n", Status);
+ NtClose(SectionHandle);
+ return Status;
+ }
+
+ /* Duplicate the handle to the section object into it */
+ Status = NtDuplicateObject(NtCurrentProcess(),
+ SectionHandle,
+ ProcessHandle,
+ &NlsMsg->SectionHandle,
+ 0,
+ 0,
+ 3);
+ NtClose(ProcessHandle);
+ return Status;
}
CSR_API(BaseSrvNlsUpdateCacheCount)
Modified: trunk/reactos/subsystems/win32/csrsrv/api.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/csrsrv/ap…
==============================================================================
--- trunk/reactos/subsystems/win32/csrsrv/api.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win32/csrsrv/api.c [iso-8859-1] Thu Aug 29 20:13:31 2013
@@ -76,11 +76,13 @@
((ServerDll->ValidTable) && !(ServerDll->ValidTable[ApiId])))
{
/* We are beyond the Maximum API ID, or it doesn't exist */
+ DPRINT1("API: %d\n", ApiId);
DPRINT1("CSRSS: %lx (%s) is invalid ApiTableIndex for %Z or is an
"
"invalid API to call from the server.\n",
- ServerDll->ValidTable[ApiId],
+ ApiId,
((ServerDll->NameTable) &&
(ServerDll->NameTable[ApiId])) ?
- ServerDll->NameTable[ApiId] : "*** UNKNOWN ***",
&ServerDll->Name);
+ ServerDll->NameTable[ApiId] : "*** UNKNOWN ***",
+ &ServerDll->Name);
// DbgBreakPoint();
ReplyMsg->Status = STATUS_ILLEGAL_FUNCTION;
return STATUS_ILLEGAL_FUNCTION;