PIMAGE_RESOURCE_DIRECTORY_ENTRY FindResourceDirectoryEntryWithName(PVOID root, PIMAGE_RESOURCE_DIRECTORY rd, LPCWSTR name) { PIMAGE_RESOURCE_DIRECTORY_ENTRY entry; entry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) GetPtr(rd, sizeof(*rd)); ULONG cnt = rd->NumberOfNamedEntries + rd->NumberOfIdEntries; for(ULONG i = 0; i < cnt; ++i) { if(entry[i].NameIsString) { PIMAGE_RESOURCE_DIR_STRING_U rname; rname = (PIMAGE_RESOURCE_DIR_STRING_U) GetPtr(root, entry[i].NameOffset); WCHAR tmp[MAX_PATH]; StringCbCopyNW(tmp, sizeof(tmp), rname->NameString, rname->Length); if(wcscmp(tmp, name) == 0) return &entry[i]; } } return NULL; }
LPWSTR WINAPI StringDupW(_In_ HANDLE hHeap, _In_ LPCWSTR lpszString) { LPWSTR lpszCopy; size_t cbCopy; HRESULT hr; if (!lpszString) return NULL; hr = StringCbLengthW(lpszString, (STRSAFE_MAX_CCH-1) * sizeof(WCHAR), &cbCopy); if (FAILED(hr)) return NULL; if ((cbCopy + sizeof(WCHAR)) <= cbCopy) return NULL; cbCopy += sizeof(WCHAR); lpszCopy = (LPWSTR) HeapAlloc(hHeap, HEAP_ZERO_MEMORY, cbCopy); if (!lpszCopy) return NULL; hr = StringCbCopyNW(lpszCopy, cbCopy, lpszString, cbCopy); if (FAILED(hr)) { HeapSafeFree(hHeap, 0, lpszCopy); return NULL; } return lpszCopy; }
STDMETHODIMP CContextMenuHandler::GetCommandString(UINT_PTR idCmd, UINT uType, UINT *pReserved, LPSTR pszName,UINT cchMax) { #ifdef DEBUG_TO_LOG_FILES char tbuf[200]; sprintf_s(tbuf,200,__FUNCTION__ ": cmd=%lu, type=%u, name=%s",(DWORD)idCmd,uType,pszName); f_log(tbuf); #endif HRESULT hr = E_INVALIDARG; const char *aHelp = ""; size_t aHelpSize = 0; const wchar_t *wHelp = L""; size_t wHelpSize = 0; const char *aVerb = ""; size_t aVerbSize = 0; const wchar_t *wVerb = L""; size_t wVerbSize = 0; if (idCmd == m_idCmdFirst + eMC_RunConsole) { aHelp = szDescrRunConsoleA; aHelpSize = sizeof(szDescrRunConsoleA); wHelp = szDescrRunConsoleW; wHelpSize = sizeof(szDescrRunConsoleW); aVerb = szVerbRunConsoleA; aVerbSize = sizeof(szVerbRunConsoleA); wVerb = szVerbRunConsoleW; wVerbSize = sizeof(szVerbRunConsoleW); } else if (idCmd == m_idCmdFirst + eMC_PostConsole) { aHelp = szDescrPostConsoleA; aHelpSize = sizeof(szDescrPostConsoleA); wHelp = szDescrPostConsoleW; wHelpSize = sizeof(szDescrPostConsoleW); aVerb = szVerbPostConsoleA; aVerbSize = sizeof(szVerbPostConsoleA); wVerb = szVerbPostConsoleW; wVerbSize = sizeof(szVerbPostConsoleW); } if (idCmd == m_idCmdFirst + eMC_RunConsoleWithTabFake) { aHelp = szDescrRunConsoleWithTabA; aHelpSize = sizeof(szDescrRunConsoleWithTabA); wHelp = szDescrRunConsoleWithTabW; wHelpSize = sizeof(szDescrRunConsoleWithTabW); aVerb = szVerbRunConsoleWithTabA; aVerbSize = sizeof(szVerbRunConsoleWithTabA); wVerb = szVerbRunConsoleW; wVerbSize = sizeof(szVerbRunConsoleWithTabW); } if (idCmd == m_idCmdFirst + eMC_PostConsoleWithTabFake) { aHelp = szDescrPostConsoleWithTabA; aHelpSize = sizeof(szDescrPostConsoleWithTabA); wHelp = szDescrPostConsoleWithTabW; wHelpSize = sizeof(szDescrPostConsoleWithTabW); aVerb = szVerbPostConsoleWithTabA; aVerbSize = sizeof(szVerbPostConsoleWithTabA); wVerb = szVerbPostConsoleWithTabW; wVerbSize = sizeof(szVerbPostConsoleWithTabW); } else { } switch(uType) { case GCS_HELPTEXTA: hr = StringCbCopyNA(pszName, cchMax, aHelp, aHelpSize); break; case GCS_HELPTEXTW: hr = StringCbCopyNW((LPWSTR)pszName, cchMax * sizeof(wchar_t), wHelp, wHelpSize); break; case GCS_VERBA: hr = StringCbCopyNA(pszName, cchMax, aVerb, aVerbSize); break; case GCS_VERBW: hr = StringCbCopyNW((LPWSTR)pszName, cchMax * sizeof(wchar_t), wVerb, wVerbSize); break; default: hr = S_OK; break; } return hr; }
static BOOLEAN CheckForValidPEAndVendor( IN HANDLE RootDirectory OPTIONAL, IN PCWSTR PathNameToFile, OUT PUNICODE_STRING VendorName ) { BOOLEAN Success = FALSE; NTSTATUS Status; HANDLE FileHandle, SectionHandle; // SIZE_T ViewSize; PVOID ViewBase; PVOID VersionBuffer = NULL; // Read-only PVOID pvData = NULL; UINT BufLen = 0; if (VendorName->MaximumLength < sizeof(UNICODE_NULL)) return FALSE; *VendorName->Buffer = UNICODE_NULL; VendorName->Length = 0; Status = OpenAndMapFile(RootDirectory, PathNameToFile, &FileHandle, &SectionHandle, &ViewBase, NULL, FALSE); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to open and map file '%S', Status 0x%08lx\n", PathNameToFile, Status); return FALSE; // Status; } /* Make sure it's a valid PE file */ if (!RtlImageNtHeader(ViewBase)) { DPRINT1("File '%S' does not seem to be a valid PE, bail out\n", PathNameToFile); Status = STATUS_INVALID_IMAGE_FORMAT; goto UnmapFile; } /* * Search for a valid executable version and vendor. * NOTE: The module is loaded as a data file, it should be marked as such. */ Status = NtGetVersionResource((PVOID)((ULONG_PTR)ViewBase | 1), &VersionBuffer, NULL); if (!NT_SUCCESS(Status)) { DPRINT1("Failed to get version resource for file '%S', Status 0x%08lx\n", PathNameToFile, Status); goto UnmapFile; } Status = NtVerQueryValue(VersionBuffer, L"\\VarFileInfo\\Translation", &pvData, &BufLen); if (NT_SUCCESS(Status)) { USHORT wCodePage = 0, wLangID = 0; WCHAR FileInfo[MAX_PATH]; wCodePage = LOWORD(*(ULONG*)pvData); wLangID = HIWORD(*(ULONG*)pvData); StringCchPrintfW(FileInfo, ARRAYSIZE(FileInfo), L"StringFileInfo\\%04X%04X\\CompanyName", wCodePage, wLangID); Status = NtVerQueryValue(VersionBuffer, FileInfo, &pvData, &BufLen); /* Fixup the Status in case pvData is NULL */ if (NT_SUCCESS(Status) && !pvData) Status = STATUS_NOT_FOUND; if (NT_SUCCESS(Status) /*&& pvData*/) { /* BufLen includes the NULL terminator count */ DPRINT1("Found version vendor: \"%S\" for file '%S'\n", pvData, PathNameToFile); StringCbCopyNW(VendorName->Buffer, VendorName->MaximumLength, pvData, BufLen * sizeof(WCHAR)); VendorName->Length = wcslen(VendorName->Buffer) * sizeof(WCHAR); Success = TRUE; } } if (!NT_SUCCESS(Status)) DPRINT1("No version vendor found for file '%S'\n", PathNameToFile); UnmapFile: /* Finally, unmap and close the file */ UnMapFile(SectionHandle, ViewBase); NtClose(FileHandle); return Success; }
HRESULT StringCbCopyW( LPWSTR pszDest, size_t cbDest, LPCWSTR pszSrc){ return StringCbCopyNW(pszDest, cbDest, pszSrc, cbDest); }
PEVENTLOGRECORD LogfAllocAndBuildNewRecord(PSIZE_T pRecSize, ULONG Time, USHORT wType, USHORT wCategory, ULONG dwEventId, PUNICODE_STRING SourceName, PUNICODE_STRING ComputerName, ULONG dwSidLength, PSID pUserSid, USHORT wNumStrings, PWSTR pStrings, ULONG dwDataSize, PVOID pRawData) { SIZE_T RecSize; SIZE_T SourceNameSize, ComputerNameSize, StringLen; PBYTE Buffer; PEVENTLOGRECORD pRec; PWSTR str; UINT i, pos; SourceNameSize = (SourceName && SourceName->Buffer) ? SourceName->Length : 0; ComputerNameSize = (ComputerName && ComputerName->Buffer) ? ComputerName->Length : 0; RecSize = sizeof(EVENTLOGRECORD) + /* Add the sizes of the strings, NULL-terminated */ SourceNameSize + ComputerNameSize + 2*sizeof(UNICODE_NULL); /* Align on DWORD boundary for the SID */ RecSize = ROUND_UP(RecSize, sizeof(ULONG)); RecSize += dwSidLength; /* Add the sizes for the strings array */ ASSERT((pStrings == NULL && wNumStrings == 0) || (pStrings != NULL && wNumStrings >= 0)); for (i = 0, str = pStrings; i < wNumStrings; i++) { StringLen = wcslen(str) + 1; // str must be != NULL RecSize += StringLen * sizeof(WCHAR); str += StringLen; } /* Add the data size */ RecSize += dwDataSize; /* Align on DWORD boundary for the full structure */ RecSize = ROUND_UP(RecSize, sizeof(ULONG)); /* Size of the trailing 'Length' member */ RecSize += sizeof(ULONG); Buffer = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, RecSize); if (!Buffer) { DPRINT1("Cannot allocate heap!\n"); return NULL; } pRec = (PEVENTLOGRECORD)Buffer; pRec->Length = RecSize; pRec->Reserved = LOGFILE_SIGNATURE; /* * Do not assign here any precomputed record number to the event record. * The true record number will be assigned atomically and sequentially in * LogfWriteRecord, so that all the event records will have consistent and * unique record numbers. */ pRec->RecordNumber = 0; /* * Set the generated time, and temporarily set the written time * with the generated time. */ pRec->TimeGenerated = Time; pRec->TimeWritten = Time; pRec->EventID = dwEventId; pRec->EventType = wType; pRec->EventCategory = wCategory; pos = sizeof(EVENTLOGRECORD); /* NOTE: Equivalents of RtlStringCbCopyUnicodeString calls */ if (SourceNameSize) { StringCbCopyNW((PWSTR)(Buffer + pos), SourceNameSize + sizeof(UNICODE_NULL), SourceName->Buffer, SourceNameSize); } pos += SourceNameSize + sizeof(UNICODE_NULL); if (ComputerNameSize) { StringCbCopyNW((PWSTR)(Buffer + pos), ComputerNameSize + sizeof(UNICODE_NULL), ComputerName->Buffer, ComputerNameSize); } pos += ComputerNameSize + sizeof(UNICODE_NULL); /* Align on DWORD boundary for the SID */ pos = ROUND_UP(pos, sizeof(ULONG)); pRec->UserSidLength = 0; pRec->UserSidOffset = 0; if (dwSidLength) { RtlCopyMemory(Buffer + pos, pUserSid, dwSidLength); pRec->UserSidLength = dwSidLength; pRec->UserSidOffset = pos; pos += dwSidLength; } pRec->StringOffset = pos; for (i = 0, str = pStrings; i < wNumStrings; i++) { StringLen = wcslen(str) + 1; // str must be != NULL StringCchCopyW((PWSTR)(Buffer + pos), StringLen, str); str += StringLen; pos += StringLen * sizeof(WCHAR); } pRec->NumStrings = wNumStrings; pRec->DataLength = 0; pRec->DataOffset = 0; if (dwDataSize) { RtlCopyMemory(Buffer + pos, pRawData, dwDataSize); pRec->DataLength = dwDataSize; pRec->DataOffset = pos; pos += dwDataSize; } /* Align on DWORD boundary for the full structure */ pos = ROUND_UP(pos, sizeof(ULONG)); /* Initialize the trailing 'Length' member */ *((PDWORD)(Buffer + pos)) = RecSize; *pRecSize = RecSize; return pRec; }
// This enumerates a tile for the info in _pkiulSetSerialization. See the SetSerialization function comment for // more information. HRESULT CSampleProvider::_EnumerateSetSerialization() { KERB_INTERACTIVE_LOGON* pkil = &_pkiulSetSerialization->Logon; _bAutoSubmitSetSerializationCred = false; _bDefaultToFirstCredential = false; // Since this provider only enumerates local users (not domain users) we are ignoring the domain passed in. // However, please note that if you receive a serialized cred of just a domain name, that domain name is meant // to be the default domain for the tiles (or for the empty tile if you have one). Also, depending on your scenario, // the presence of a domain other than what you're expecting might be a clue that you shouldn't handle // the SetSerialization. For example, in this sample, we could choose to not accept a serialization for a cred // that had something other than the local machine name as the domain. // Use a "long" (MAX_PATH is arbitrary) buffer because it's hard to predict what will be // in the incoming values. A DNS-format domain name, for instance, can be longer than DNLEN. WCHAR wszUsername[MAX_PATH] = {0}; WCHAR wszPassword[MAX_PATH] = {0}; // since this sample assumes local users, we'll ignore domain. If you wanted to handle the domain // case, you'd have to update CSampleCredential::Initialize to take a domain. HRESULT hr = StringCbCopyNW(wszUsername, sizeof(wszUsername), pkil->UserName.Buffer, pkil->UserName.Length); if (SUCCEEDED(hr)) { hr = StringCbCopyNW(wszPassword, sizeof(wszPassword), pkil->Password.Buffer, pkil->Password.Length); if (SUCCEEDED(hr)) { CSampleCredential* pCred = new CSampleCredential(); if (pCred) { hr = pCred->Initialize(_cpus, s_rgCredProvFieldDescriptors, s_rgFieldStatePairs, _dwCredUIFlags, wszUsername, wszPassword); if (SUCCEEDED(hr)) { // for the purposes of this sample, when we enumerate the SetSerialization cred, we only enumerate // that cred and no others, so we can assume it just goes in slot 0. _rgpCredentials[0] = pCred; //if we were able to create a cred, default to it _bDefaultToFirstCredential = true; } } else { hr = E_OUTOFMEMORY; } // If we were passed all the info we need (in this case username & password), we're going to automatically submit this credential. // (if we're in CPUS_LOGON that is. In credUI we want the user to at least click the tile to choose to use those creds) if (SUCCEEDED(hr) && (0 < wcslen(wszPassword))) { _bAutoSubmitSetSerializationCred = true; } } } return hr; }
HRESULT EnumerateNext(LPITEMIDLIST* ppidl) { BYTE dirbuffer[2048]; if (!NT_SUCCESS(NtQueryDirectoryObject(m_directory, dirbuffer, 2048, TRUE, m_first, &m_enumContext, NULL))) return S_FALSE; m_first = FALSE; // if ppidl is NULL, assume the caller was Skip(), // so we don't care about the info if (!ppidl) return S_OK; POBJECT_DIRECTORY_INFORMATION info = (POBJECT_DIRECTORY_INFORMATION) dirbuffer; if (info->Name.Buffer) { StringCbCopyNW(m_pend, sizeof(buffer), info->Name.Buffer, info->Name.Length); } OBJECT_TYPE otype = MapTypeNameToType(info->TypeName.Buffer, info->TypeName.Length); DWORD entryBufferLength = FIELD_OFFSET(NtPidlEntry, entryName) + sizeof(WCHAR); if (info->Name.Buffer) entryBufferLength += info->Name.Length; if (otype < 0) { entryBufferLength += FIELD_OFFSET(NtPidlTypeData, typeName) + sizeof(WCHAR); if (info->TypeName.Buffer) { entryBufferLength += info->TypeName.Length; } } // allocate space for the terminator entryBufferLength += FIELD_OFFSET(SHITEMID, abID); NtPidlEntry* entry = (NtPidlEntry*) CoTaskMemAlloc(entryBufferLength); if (!entry) return E_OUTOFMEMORY; memset(entry, 0, entryBufferLength); entry->cb = FIELD_OFFSET(NtPidlEntry, entryName); entry->magic = NT_OBJECT_PIDL_MAGIC; entry->objectType = otype; if (info->Name.Buffer) { entry->entryNameLength = info->Name.Length; StringCbCopyNW(entry->entryName, entryBufferLength, info->Name.Buffer, info->Name.Length); entry->cb += entry->entryNameLength + sizeof(WCHAR); } else { entry->entryNameLength = 0; entry->entryName[0] = 0; entry->cb += sizeof(WCHAR); } if (otype < 0) { NtPidlTypeData * typedata = (NtPidlTypeData*) ((PBYTE) entry + entry->cb); DWORD remainingSpace = entryBufferLength - ((PBYTE) (typedata->typeName) - (PBYTE) entry); if (info->TypeName.Buffer) { typedata->typeNameLength = info->TypeName.Length; StringCbCopyNW(typedata->typeName, remainingSpace, info->TypeName.Buffer, info->TypeName.Length); entry->cb += typedata->typeNameLength + sizeof(WCHAR); } else { typedata->typeNameLength = 0; typedata->typeName[0] = 0; entry->cb += typedata->typeNameLength + sizeof(WCHAR); } } *ppidl = (LPITEMIDLIST) entry; return S_OK; }
HRESULT NextValue(LPITEMIDLIST* ppidl) { WCHAR name[MAX_PATH]; DWORD cchName = _countof(name); DWORD type = 0; DWORD dataSize = 0; if (RegEnumValueW(m_hkey, m_idx++, name, &cchName, 0, &type, NULL, &dataSize)) return S_FALSE; REG_ENTRY_TYPE otype = REG_ENTRY_VALUE; DWORD entryBufferLength = FIELD_OFFSET(RegPidlEntry, entryName) + sizeof(WCHAR) + cchName * sizeof(WCHAR); #define MAX_EMBEDDED_DATA 32 BOOL copyData = dataSize <= MAX_EMBEDDED_DATA; if (copyData) { entryBufferLength += dataSize + sizeof(WCHAR); otype = REG_ENTRY_VALUE_WITH_CONTENT; } // allocate space for the terminator entryBufferLength += FIELD_OFFSET(SHITEMID, abID); RegPidlEntry* entry = (RegPidlEntry*) CoTaskMemAlloc(entryBufferLength); if (!entry) return E_OUTOFMEMORY; memset(entry, 0, entryBufferLength); entry->cb = FIELD_OFFSET(RegPidlEntry, entryName); entry->magic = REGISTRY_PIDL_MAGIC; entry->entryType = otype; entry->contentType = type; if (cchName > 0) { entry->entryNameLength = cchName * sizeof(WCHAR); StringCbCopyNW(entry->entryName, entryBufferLength, name, entry->entryNameLength); entry->cb += entry->entryNameLength + sizeof(WCHAR); } else { entry->entryNameLength = 0; entry->entryName[0] = 0; entry->cb += sizeof(WCHAR); } if (copyData) { PBYTE contentData = (PBYTE) ((PBYTE) entry + entry->cb); entry->contentsLength = dataSize; // In case it's an unterminated string, RegGetValue will add the NULL termination dataSize += sizeof(WCHAR); if (!RegQueryValueExW(m_hkey, name, NULL, NULL, contentData, &dataSize)) { entry->cb += entry->contentsLength + sizeof(WCHAR); } else { entry->contentsLength = 0; entry->cb += sizeof(WCHAR); } } if (ppidl) *ppidl = (LPITEMIDLIST) entry; return S_OK; }
HRESULT NextKey(LPITEMIDLIST* ppidl) { WCHAR name[MAX_PATH]; DWORD cchName = _countof(name); WCHAR className[MAX_PATH]; DWORD cchClass = _countof(className); if (RegEnumKeyExW(m_hkey, m_idx++, name, &cchName, 0, className, &cchClass, NULL)) return S_FALSE; name[cchName] = 0; className[cchClass] = 0; REG_ENTRY_TYPE otype = REG_ENTRY_KEY; DWORD entryBufferLength = FIELD_OFFSET(RegPidlEntry, entryName) + sizeof(WCHAR) + cchName * sizeof(WCHAR); if (cchClass > 0) { entryBufferLength += sizeof(WCHAR) + cchClass * sizeof(WCHAR); } // allocate space for the terminator entryBufferLength += FIELD_OFFSET(SHITEMID, abID); RegPidlEntry* entry = (RegPidlEntry*) CoTaskMemAlloc(entryBufferLength); if (!entry) return E_OUTOFMEMORY; memset(entry, 0, entryBufferLength); entry->cb = FIELD_OFFSET(RegPidlEntry, entryName); entry->magic = REGISTRY_PIDL_MAGIC; entry->entryType = otype; if (cchName > 0) { entry->entryNameLength = cchName * sizeof(WCHAR); StringCbCopyNW(entry->entryName, entryBufferLength, name, entry->entryNameLength); entry->cb += entry->entryNameLength + sizeof(WCHAR); } else { entry->entryNameLength = 0; entry->entryName[0] = 0; entry->cb += sizeof(WCHAR); } if (cchClass) { PWSTR contentData = (PWSTR) ((PBYTE) entry + entry->cb); DWORD remainingSpace = entryBufferLength - entry->cb; entry->contentsLength = cchClass * sizeof(WCHAR); StringCbCopyNW(contentData, remainingSpace, className, entry->contentsLength); entry->cb += entry->contentsLength + sizeof(WCHAR); } if (ppidl) *ppidl = (LPITEMIDLIST) entry; return S_OK; }