Eric Pouech : ntdll: Implemented RtlFindActivationContextSectionString.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Jul 26 06:36:47 CDT 2007


Module: wine
Branch: master
Commit: 6792a9a92ea3b0e9a77d9a594b327c25855e1fce
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=6792a9a92ea3b0e9a77d9a594b327c25855e1fce

Author: Eric Pouech <eric.pouech at 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);




More information about the wine-cvs mailing list