/* * @implemented */ VOID WINAPI ReleaseActCtx(IN HANDLE hActCtx) { /* Call the native API */ RtlReleaseActivationContext(hActCtx); }
VOID NTAPI BasepFreeActivationContextActivationBlock(IN PBASEP_ACTCTX_BLOCK ActivationBlock) { /* Exit if there was nothing passed in */ if (!ActivationBlock) return; /* Do we have a context? */ if (ActivationBlock->ActivationContext) { /* Release and clear it */ RtlReleaseActivationContext(ActivationBlock->ActivationContext); ActivationBlock->ActivationContext = NULL; } /* Free the block */ RtlFreeHeap(RtlGetProcessHeap(), 0, ActivationBlock); }
LPCWSTR FASTCALL ClassNameToVersion( LPCTSTR lpszClass, LPCWSTR lpszMenuName, LPCWSTR *plpLibFileName, HANDLE *pContext, BOOL bAnsi) { NTSTATUS Status; UNICODE_STRING SectionName; WCHAR SeactionNameBuf[MAX_PATH] = {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; }
NTSTATUS NTAPI BasepAllocateActivationContextActivationBlock(IN DWORD Flags, IN PVOID CompletionRoutine, IN PVOID CompletionContext, OUT PBASEP_ACTCTX_BLOCK *ActivationBlock) { NTSTATUS Status; ACTIVATION_CONTEXT_BASIC_INFORMATION ContextInfo; /* Clear the info structure */ ContextInfo.dwFlags = 0; ContextInfo.hActCtx = NULL; /* Assume failure */ if (ActivationBlock) *ActivationBlock = NULL; /* Only support valid flags */ if (Flags & ~(1 | 2)) // FIXME: What are they? 2 looks like BASEP_ACTCTX_FORCE_BLOCK { /* Fail if unknown flags are passed in */ Status = STATUS_INVALID_PARAMETER_1; goto Quickie; } /* Caller should have passed in an activation block */ if (!ActivationBlock) { /* Fail otherwise */ Status = STATUS_INVALID_PARAMETER_4; goto Quickie; } /* Query RTL for information on the current activation context */ Status = RtlQueryInformationActivationContext(RTL_QUERY_ACTIVATION_CONTEXT_FLAG_USE_ACTIVE_ACTIVATION_CONTEXT, NULL, NULL, ActivationContextBasicInformation, &ContextInfo, sizeof(ContextInfo), NULL); if (!NT_SUCCESS(Status)) { /* Failed -- bail out */ DPRINT1("SXS: %s - Failure getting active activation context; ntstatus %08lx\n", __FUNCTION__, Status); goto Quickie; } /* Check if the current one should be freed */ if (ContextInfo.dwFlags & 1) { /* Release and clear it */ RtlReleaseActivationContext(ContextInfo.hActCtx); ContextInfo.hActCtx = NULL; } /* Check if there's an active context, or if the caller is forcing one */ if (!(Flags & 2) || (ContextInfo.hActCtx)) { /* Allocate the block */ *ActivationBlock = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(BASEP_ACTCTX_BLOCK)); if (!(*ActivationBlock)) { /* Ran out of memory, fail */ Status = STATUS_NO_MEMORY; goto Quickie; } /* Fill it out */ (*ActivationBlock)->ActivationContext = ContextInfo.hActCtx; (*ActivationBlock)->Flags = 0; if (Flags & 1) (*ActivationBlock)->Flags |= 1; // Not sure about this flag (*ActivationBlock)->CompletionRoutine = CompletionRoutine; (*ActivationBlock)->CompletionContext = CompletionContext; /* Tell Quickie below not to free anything, since this is success */ ContextInfo.hActCtx = NULL; } /* Set success status */ Status = STATUS_SUCCESS; Quickie: /* Failure or success path, return to caller and free on failure */ if (ContextInfo.hActCtx) RtlReleaseActivationContext(ContextInfo.hActCtx); return Status; }