Module: wine Branch: master Commit: 6792a9a92ea3b0e9a77d9a594b327c25855e1fce URL: http://source.winehq.org/git/wine.git/?a=commit;h=6792a9a92ea3b0e9a77d9a594b...
Author: Eric Pouech eric.pouech@wanadoo.fr Date: Wed Jul 25 20:37:36 2007 +0200
ntdll: Implemented RtlFindActivationContextSectionString.
---
dlls/kernel32/actctx.c | 41 +++----------- dlls/ntdll/actctx.c | 140 ++++++++++++++++++++++++++++++++++++++++++++++++ dlls/ntdll/ntdll.spec | 2 +- include/winternl.h | 1 + 4 files changed, 151 insertions(+), 33 deletions(-)
diff --git a/dlls/kernel32/actctx.c b/dlls/kernel32/actctx.c index 2d1e11c..33aa10e 100644 --- a/dlls/kernel32/actctx.c +++ b/dlls/kernel32/actctx.c @@ -234,39 +234,16 @@ BOOL WINAPI FindActCtxSectionStringW(DWORD dwFlags, const GUID* lpExtGuid, ULONG ulId, LPCWSTR lpSearchStr, PACTCTX_SECTION_KEYED_DATA pInfo) { - FIXME("%08x %s %u %s %p\n", dwFlags, debugstr_guid(lpExtGuid), - ulId, debugstr_w(lpSearchStr), pInfo); - - if (lpExtGuid) - { - FIXME("expected lpExtGuid == NULL\n"); - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - if (dwFlags & ~FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX) - { - FIXME("unknown dwFlags %08x\n", dwFlags); - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - if (!pInfo || pInfo->cbSize < sizeof (ACTCTX_SECTION_KEYED_DATA)) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - pInfo->ulDataFormatVersion = 1; - pInfo->lpData = NULL; - pInfo->lpSectionGlobalData = NULL; - pInfo->ulSectionGlobalDataLength = 0; - pInfo->lpSectionBase = NULL; - pInfo->ulSectionTotalLength = 0; - pInfo->hActCtx = ACTCTX_FAKE_HANDLE; - pInfo->ulAssemblyRosterIndex = 0; + UNICODE_STRING us; + NTSTATUS status;
- return TRUE; + RtlInitUnicodeString(&us, lpSearchStr); + if ((status = RtlFindActivationContextSectionString(dwFlags, lpExtGuid, ulId, &us, pInfo))) + { + SetLastError(RtlNtStatusToDosError(status)); + return FALSE; + } + return TRUE; }
/*********************************************************************** diff --git a/dlls/ntdll/actctx.c b/dlls/ntdll/actctx.c index 14336c0..98ffd38 100644 --- a/dlls/ntdll/actctx.c +++ b/dlls/ntdll/actctx.c @@ -1972,6 +1972,102 @@ static NTSTATUS find_query_actctx( HANDLE *handle, DWORD flags ) return status; }
+static NTSTATUS fill_keyed_data(PACTCTX_SECTION_KEYED_DATA data, PVOID v1, PVOID v2, unsigned int i) +{ + data->ulDataFormatVersion = 1; + data->lpData = v1; + data->ulLength = 20; /* FIXME */ + data->lpSectionGlobalData = NULL; /* FIXME */ + data->ulSectionGlobalDataLength = 0; /* FIXME */ + data->lpSectionBase = v2; + data->ulSectionTotalLength = 0; /* FIXME */ + data->hActCtx = NULL; + if (data->cbSize >= offsetof(ACTCTX_SECTION_KEYED_DATA, ulAssemblyRosterIndex) + sizeof(ULONG)) + data->ulAssemblyRosterIndex = i + 1; + + return STATUS_SUCCESS; +} + +static NTSTATUS find_dll_redirection(ACTIVATION_CONTEXT* actctx, const UNICODE_STRING *section_name, + PACTCTX_SECTION_KEYED_DATA data) +{ + unsigned int i, j, snlen = section_name->Length / sizeof(WCHAR); + + for (i = 0; i < actctx->num_assemblies; i++) + { + struct assembly *assembly = &actctx->assemblies[i]; + for (j = 0; j < assembly->num_dlls; j++) + { + struct dll_redirect *dll = &assembly->dlls[j]; + if (!strncmpiW(section_name->Buffer, dll->name, snlen) && !dll->name[snlen]) + return fill_keyed_data(data, dll, assembly, i); + } + } + return STATUS_SXS_KEY_NOT_FOUND; +} + +static NTSTATUS find_window_class(ACTIVATION_CONTEXT* actctx, const UNICODE_STRING *section_name, + PACTCTX_SECTION_KEYED_DATA data) +{ + unsigned int i, j, k, snlen = section_name->Length / sizeof(WCHAR); + + for (i = 0; i < actctx->num_assemblies; i++) + { + struct assembly *assembly = &actctx->assemblies[i]; + for (j = 0; j < assembly->num_dlls; j++) + { + struct dll_redirect *dll = &assembly->dlls[j]; + for (k = 0; k < dll->entities.num; k++) + { + struct entity *entity = &dll->entities.base[k]; + if (entity->kind == ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION) + { + if (!strncmpiW(section_name->Buffer, entity->u.class.name, snlen) && !entity->u.class.name[snlen]) + return fill_keyed_data(data, entity, dll, i); + } + } + } + } + return STATUS_SXS_KEY_NOT_FOUND; +} + +static NTSTATUS find_string(ACTIVATION_CONTEXT* actctx, ULONG section_kind, + const UNICODE_STRING *section_name, + DWORD flags, PACTCTX_SECTION_KEYED_DATA data) +{ + NTSTATUS status; + + switch (section_kind) + { + case ACTIVATION_CONTEXT_SECTION_DLL_REDIRECTION: + status = find_dll_redirection(actctx, section_name, data); + break; + case ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION: + status = find_window_class(actctx, section_name, data); + break; + case ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION: + case ACTIVATION_CONTEXT_SECTION_COM_INTERFACE_REDIRECTION: + case ACTIVATION_CONTEXT_SECTION_COM_TYPE_LIBRARY_REDIRECTION: + case ACTIVATION_CONTEXT_SECTION_COM_PROGID_REDIRECTION: + case ACTIVATION_CONTEXT_SECTION_GLOBAL_OBJECT_RENAME_TABLE: + case ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES: + FIXME("Unsupported yet section_kind %x\n", section_kind); + return STATUS_SXS_SECTION_NOT_FOUND; + default: + WARN("Unknown section_kind %x\n", section_kind); + return STATUS_SXS_SECTION_NOT_FOUND; + } + + if (status != STATUS_SUCCESS) return status; + + if (flags & FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX) + { + actctx_addref(actctx); + data->hActCtx = actctx; + } + return STATUS_SUCCESS; +} + /* initialize the activation context for the current process */ void actctx_init(void) { @@ -2434,3 +2530,47 @@ NTSTATUS WINAPI RtlQueryInformationActivationContext( ULONG flags, HANDLE handle } return STATUS_SUCCESS; } + +/*********************************************************************** + * RtlFindActivationContextSectionString (NTDLL.@) + * + * Find information about a string in an activation context. + * FIXME: function signature/prototype may be wrong + */ +NTSTATUS WINAPI RtlFindActivationContextSectionString( ULONG flags, const GUID *guid, ULONG section_kind, + const UNICODE_STRING *section_name, PVOID ptr ) +{ + PACTCTX_SECTION_KEYED_DATA data = ptr; + NTSTATUS status = STATUS_SXS_KEY_NOT_FOUND; + + TRACE("%08x %s %u %s %p\n", flags, debugstr_guid(guid), section_kind, + debugstr_us(section_name), data); + + if (guid) + { + FIXME("expected guid == NULL\n"); + return STATUS_INVALID_PARAMETER; + } + if (flags & ~FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX) + { + FIXME("unknown flags %08x\n", flags); + return STATUS_INVALID_PARAMETER; + } + if (!data || data->cbSize < offsetof(ACTCTX_SECTION_KEYED_DATA, ulAssemblyRosterIndex) || + !section_name || !section_name->Buffer) + { + WARN("invalid parameter\n"); + return STATUS_INVALID_PARAMETER; + } + + if (NtCurrentTeb()->ActivationContextStack.ActiveFrame) + { + ACTIVATION_CONTEXT *actctx = check_actctx(NtCurrentTeb()->ActivationContextStack.ActiveFrame->ActivationContext); + if (actctx) status = find_string( actctx, section_kind, section_name, flags, data ); + } + + if (status != STATUS_SUCCESS) + status = find_string( process_actctx, section_kind, section_name, flags, data ); + + return status; +} diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 6f05412..d12123a 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -574,7 +574,7 @@ @ stdcall RtlFillMemoryUlong(ptr long long) @ stub RtlFinalReleaseOutOfProcessMemoryStream @ stub RtlFindActivationContextSectionGuid -@ stub RtlFindActivationContextSectionString +@ stdcall RtlFindActivationContextSectionString(long ptr long ptr ptr) @ stdcall RtlFindCharInUnicodeString(long ptr ptr ptr) @ stdcall RtlFindClearBits(ptr long long) @ stdcall RtlFindClearBitsAndSet(ptr long long) diff --git a/include/winternl.h b/include/winternl.h index 8ad8329..d1764cd 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -2081,6 +2081,7 @@ LONGLONG WINAPI RtlExtendedMagicDivide(LONGLONG,LONGLONG,INT); LONGLONG WINAPI RtlExtendedIntegerMultiply(LONGLONG,INT); LONGLONG WINAPI RtlExtendedLargeIntegerDivide(LONGLONG,INT,INT *);
+NTSTATUS WINAPI RtlFindActivationContextSectionString(ULONG,const GUID*,ULONG,const UNICODE_STRING*,PVOID); NTSTATUS WINAPI RtlFindCharInUnicodeString(int,const UNICODE_STRING*,const UNICODE_STRING*,USHORT*); ULONG WINAPI RtlFindClearBits(PCRTL_BITMAP,ULONG,ULONG); ULONG WINAPI RtlFindClearBitsAndSet(PRTL_BITMAP,ULONG,ULONG);