HRESULT CTsTeleportShellExt::AnnounceTransfer(__in_z LPTSTR szPartial, BOOL bDir) { HRESULT hr; PTELEP_PACKET_HEADER pPacket = NULL; // // Send start packet for file or dir // size_t Len = _tcslen(szPartial); USHORT DataLen; hr = SizeTToUShort(Len, &DataLen); LEAVE_IF_FAILED("SizeTToUShort (0x%Ix) failed", Len); hr = UShortAdd(DataLen, 1, &DataLen); LEAVE_IF_FAILED("UShortAdd (0x%4x, 1) failed", DataLen); hr = UShortMult(DataLen, sizeof(TCHAR), &DataLen); LEAVE_IF_FAILED("UShortMult (0x%4x, %d) failed", DataLen, sizeof(TCHAR)); hr = UShortAdd(DataLen, sizeof(TELEP_PACKET_HEADER), &DataLen); LEAVE_IF_FAILED("UShortMult (0x%4x, %d) failed", DataLen, sizeof(TELEP_PACKET_HEADER)); USHORT Flags = 0; if (bDir) { Flags |= TELET_FLAG_DIRECTORY; } pPacket = NewPacket(PacketTypeFileStart, DataLen, Flags); // throwing! LPWSTR pData = (LPWSTR) (pPacket+1); CopyMemory(pData, szPartial, pPacket->PacketSize); hr = SendPacket(pPacket); LEAVE_IF_FAILED("SendPacket (Start, %s) failed", szPartial); _Function_Exit: if (pPacket) { delete [] pPacket; } return hr; }
// // This function copies the length of pwz and the pointer pwz into the UNICODE_STRING structure // This function is intended for serializing a credential in GetSerialization only. // Note that this function just makes a copy of the string pointer. It DOES NOT ALLOCATE storage! // Be very, very sure that this is what you want, because it probably isn't outside of the // exact GetSerialization call where the sample uses it. // HRESULT UnicodeStringInitWithString( PWSTR pwz, UNICODE_STRING* pus ) { HRESULT hr; if (pwz) { size_t lenString; hr = StringCchLengthW(pwz, USHORT_MAX, &(lenString)); if (SUCCEEDED(hr)) { USHORT usCharCount; hr = SizeTToUShort(lenString, &usCharCount); if (SUCCEEDED(hr)) { USHORT usSize; hr = SizeTToUShort(sizeof(WCHAR), &usSize); if (SUCCEEDED(hr)) { hr = UShortMult(usCharCount, usSize, &(pus->Length)); // Explicitly NOT including NULL terminator if (SUCCEEDED(hr)) { pus->MaximumLength = pus->Length; pus->Buffer = pwz; hr = S_OK; } else { hr = HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW); } } } } } else { hr = E_INVALIDARG; } return hr; }
// Add an ACE to an ACL, expanding the ACL if needed. HRESULT AddAceToAcl(LPVOID pNewAce, PACL *ppAcl, bool bAddToEndOfList) { DWORD addPosition = bAddToEndOfList ? MAXDWORD : 0; BOOL bResult = FALSE; DWORD errorCode = S_OK; PACL biggerDACL = nullptr; HRESULT hr = S_OK; ACL_SIZE_INFORMATION aclInformation; WORD aceSize; DWORD oldSize; USHORT uSize; DWORD dwNewSizeNeeded; if ( !ARGUMENT_PRESENT(pNewAce) || !ARGUMENT_PRESENT(*ppAcl) ) { return E_INVALIDARG; } bResult = AddAce( *ppAcl, ACL_REVISION, addPosition, pNewAce, ((PACE_HEADER)pNewAce)->AceSize ); // See if we failed due to an insufficient buffer size if ( !bResult ) { errorCode = GetLastError(); if ( errorCode == ERROR_INSUFFICIENT_BUFFER ) { // Not enough space. Allocate a bigger ACL. bResult = GetAclInformation( *ppAcl, &aclInformation, sizeof(aclInformation), AclSizeInformation ); FailGracefullyGLE(bResult, L"GetAclInformation"); aceSize = ((PACE_HEADER)pNewAce)->AceSize; oldSize = aclInformation.AclBytesInUse; // Can't overflow WORD boundary hr = UShortAdd(aceSize, (USHORT)oldSize, &uSize); FailGracefully(hr, L"UShortAdd"); // Give us some extra space so that we don't have to keep // reallocating. hr = UShortMult(uSize, 2, &uSize); FailGracefully(hr, L"UShortMult"); dwNewSizeNeeded = (DWORD)uSize; // Align to a DWORD dwNewSizeNeeded = (dwNewSizeNeeded + (sizeof(DWORD) - 1)) & 0xfffffffc; // Make sure the alignment didn't overflow the size of a WORD // (the process of aligning can add up to 3) if ( dwNewSizeNeeded > USHORT_MAX ) { // It's safe to subtrat now (despite the "size needed" name) // because we overestimated earlier by multiplying by 2. dwNewSizeNeeded -= 4; } biggerDACL = (PACL)LocalAlloc(LPTR, dwNewSizeNeeded); if ( !biggerDACL ) { wprintf(L"LocalAlloc failed.\n"); hr = E_OUTOFMEMORY; goto exit_gracefully; } // Note: no need to initialize the new ACL memcpy(biggerDACL, *ppAcl, oldSize); // This cast is safe because we checked for overflow earlier biggerDACL->AclSize = (WORD)dwNewSizeNeeded; *ppAcl = biggerDACL; // Make sure this doesn't get freed later biggerDACL = nullptr; bResult = AddAce( *ppAcl, ACL_REVISION, addPosition, pNewAce, ((PACE_HEADER)pNewAce)->AceSize ); FailGracefullyGLE(bResult, L"AddAce"); } else { return HRESULT_FROM_WIN32(errorCode); } } exit_gracefully: LocalFree(biggerDACL); return hr; }