[WIP User32 SxS]
authorJames Tabor <james.tabor@reactos.org>
Wed, 23 May 2012 20:21:29 +0000 (20:21 +0000)
committerJames Tabor <james.tabor@reactos.org>
Wed, 23 May 2012 20:21:29 +0000 (20:21 +0000)
- Add SxS for classes, still not plugged in for a year now.
- Need more information on global headers to support class contexts. ATM the headers are local, for noting what is needed.

svn path=/trunk/; revision=56652

reactos/win32ss/user/user32/windows/class.c

index 0d9ae49..45c43fb 100644 (file)
 #include <wine/debug.h>
 WINE_DEFAULT_DEBUG_CHANNEL(user32);
 
+/* From rtl/actctx.c and must match! */
+struct entity
+{
+    DWORD  kind;  // Activation context type
+    WCHAR *name;  // Class name
+    WCHAR *clsid; // Not supported yet but needed for menu name.
+};
+
+struct dll_redirect
+{
+    WCHAR *name; // Dll name
+    WCHAR *hash;
+    DWORD  Data; // Junk
+};
+
+LPCWSTR
+FASTCALL
+ClassNameToVersion(
+  LPCTSTR lpszClass,
+  LPCWSTR lpszMenuName,
+  LPCWSTR *plpLibFileName,
+  HANDLE *pContext,
+  BOOL bAnsi)
+{
+   NTSTATUS Status;
+   UNICODE_STRING SectionName;
+   WCHAR SeactionNameBuf[256] = {0};
+   ACTCTX_SECTION_KEYED_DATA KeyedData = { sizeof(KeyedData) };
+
+   if (IS_ATOM(lpszClass))
+   {
+      SectionName.Buffer = (LPWSTR)&SeactionNameBuf;
+      SectionName.MaximumLength = sizeof(SeactionNameBuf);
+      if(!NtUserGetAtomName(LOWORD((DWORD_PTR)lpszClass), &SectionName))
+      {
+         return NULL;
+      }
+   }
+   else
+  {
+      if (bAnsi)
+      {
+         RtlCreateUnicodeStringFromAsciiz(&SectionName, (LPSTR)lpszClass);
+      }
+      else
+      {
+         RtlInitUnicodeString(&SectionName, lpszClass);
+      }
+   }
+   Status = RtlFindActivationContextSectionString( FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX,
+                                                   NULL,
+                                                   ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION,
+                                                  &SectionName,
+                                                  &KeyedData );
+   if (NT_SUCCESS(Status) && KeyedData.ulDataFormatVersion == 1)
+   {
+      struct dll_redirect *dll = KeyedData.lpSectionBase;
+
+      if (plpLibFileName) *plpLibFileName = dll->name;
+
+      if (lpszMenuName)
+      {
+         WCHAR * mnubuf;
+         LPWSTR mnuNameW;
+         LPSTR mnuNameA;
+         int len = 0;
+         struct entity *entity = KeyedData.lpData;
+
+         FIXME("actctx: Needs to support menu name from redirected class!");
+
+         if (entity->clsid)
+         {
+            mnubuf = entity->clsid;
+            if (bAnsi)
+            {
+               mnuNameA = (LPSTR)lpszMenuName;
+               RtlUnicodeToMultiByteN( mnuNameA, 255, (PULONG)&len, mnubuf, strlenW(mnubuf) * sizeof(WCHAR) );
+               mnuNameA[len] = 0;
+            }
+            else
+            {
+               mnuNameW = (LPWSTR)lpszMenuName;
+               len = strlenW(mnubuf) * sizeof(WCHAR);
+               RtlCopyMemory((void *)mnuNameW, mnubuf, len);
+               mnuNameW[len] = 0;
+            }
+         }
+      }
+      if (pContext) *pContext = KeyedData.hActCtx;
+   }
+
+   if (!IS_ATOM(lpszClass) && bAnsi)
+      RtlFreeUnicodeString(&SectionName);
+   if (KeyedData.hActCtx)
+      RtlReleaseActivationContext(KeyedData.hActCtx);
+
+   return lpszClass;
+}
+
+BOOL
+FASTCALL
+VersionRegisterClass(
+  PCWSTR pszClass,
+  LPCWSTR lpLibFileName,
+  HANDLE Contex,
+  HMODULE * phLibModule)
+{
+   BOOL Ret;
+   HMODULE hLibModule;
+   PREGISTERCLASSNAMEW pRegisterClassNameW;
+   UNICODE_STRING ClassName;
+   WCHAR ClassNameBuf[256] = {0};
+   RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame = { sizeof(Frame), 1 };
+
+   RtlActivateActivationContextUnsafeFast(&Frame, Contex);
+
+   Ret = FALSE;
+   hLibModule = NULL;
+
+   _SEH2_TRY
+   {
+      hLibModule = LoadLibraryW(lpLibFileName);
+      if ( hLibModule )
+      {
+         if ((pRegisterClassNameW = (void*) GetProcAddress(hLibModule, "RegisterClassNameW")))
+         {
+            if (IS_ATOM(pszClass))
+            {
+               ClassName.Buffer = (LPWSTR)&ClassNameBuf;
+               ClassName.MaximumLength = sizeof(ClassNameBuf);
+               if (!NtUserGetAtomName(LOWORD((DWORD_PTR)pszClass), &ClassName))
+               {
+                  _SEH2_YIELD(goto Error_Exit);
+               }
+               pszClass = (PCWSTR)&ClassNameBuf;
+            }
+            Ret = pRegisterClassNameW(pszClass);
+         }
+      }
+   }
+   _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+   {
+   }
+   _SEH2_END
+
+Error_Exit:
+   if ( Ret || !hLibModule )
+   {
+      if ( phLibModule ) *phLibModule = hLibModule;  
+   }
+   else
+   {
+      DWORD save_error = GetLastError();
+      FreeLibrary(hLibModule);
+      SetLastError(save_error);
+   }
+                                  
+   return Ret;
+}
+
 /*
  * @implemented
  */