Ejemplo n.º 1
0
/********************************************************************
StrAnsiAlloc - allocates or reuses dynamic ANSI string memory

NOTE: caller is responsible for freeing ppsz even if function fails
********************************************************************/
extern "C" HRESULT DAPI StrAnsiAlloc(
	__inout LPSTR* ppsz,
	__in DWORD_PTR cch
	)
{
	Assert(ppsz && cch);
	HRESULT hr = S_OK;
	LPSTR psz = NULL;

	if (cch >= MAXDWORD / sizeof(WCHAR))
	{
		ExitOnFailure1(hr = E_OUTOFMEMORY, "Not enough memory to allocate string of size: %d", cch);
	}

	if (*ppsz)
		psz = static_cast<LPSTR>(MemReAlloc(*ppsz, sizeof(CHAR) * cch, FALSE));
	else
		psz = static_cast<LPSTR>(MemAlloc(sizeof(CHAR) * cch, TRUE));

	ExitOnNull1(psz, hr, E_OUTOFMEMORY, "failed to allocate string, len: %d", cch);

	*ppsz = psz;
LExit:
	return hr;
}
Ejemplo n.º 2
0
static HRESULT CreateSidFromDomainRidPair(
    PSID pDomainSid,
    DWORD dwRid,
    PSID* ppSid
    )
{
    HRESULT hr = S_OK;
    PSID pSid = NULL;

    // get domain SID sub authority count
    UCHAR ucSubAuthorityCount = *::GetSidSubAuthorityCount(pDomainSid);

    // allocate SID buffer
    DWORD dwLengthRequired = ::GetSidLengthRequired(ucSubAuthorityCount + (UCHAR)1);
    if (*ppSid)
    {
        SIZE_T ccb = ::HeapSize(::GetProcessHeap(), 0, *ppSid);
        if (-1 == ccb)
            ExitOnFailure(hr = E_FAIL, "Failed to get size of SID buffer");

        if (ccb < dwLengthRequired)
        {
            pSid = (PSID)::HeapReAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, *ppSid, dwLengthRequired);
            ExitOnNull1(pSid, hr, E_OUTOFMEMORY, "Failed to reallocate buffer for SID, len: %d", dwLengthRequired);
            *ppSid = pSid;
        }
    }
    else
    {
        *ppSid = (PSID)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, dwLengthRequired);
        ExitOnNull1(*ppSid, hr, E_OUTOFMEMORY, "Failed to allocate buffer for SID, len: %d", dwLengthRequired);
    }

    ::InitializeSid(*ppSid, ::GetSidIdentifierAuthority(pDomainSid), ucSubAuthorityCount + (UCHAR)1);

    // copy sub autorities
    DWORD i = 0;
    for (; i < ucSubAuthorityCount; i++)
        *::GetSidSubAuthority(*ppSid, i) = *::GetSidSubAuthority(pDomainSid, i);
    *::GetSidSubAuthority(*ppSid, i) = dwRid;

    hr = S_OK;

LExit:
    return hr;
}
Ejemplo n.º 3
0
/********************************************************************
StrAllocStringAnsi - allocates or reuses dynamic string memory and copies in an existing ANSI string

NOTE: caller is responsible for freeing ppwz even if function fails
NOTE: cchSource must equal the length of wzSource (not including the NULL terminator)
NOTE: if cchSource == 0, length of wzSource is used instead
********************************************************************/
extern "C" HRESULT DAPI StrAllocStringAnsi(
	__inout LPWSTR* ppwz,
	__in LPCSTR szSource,
	__in DWORD_PTR cchSource,
	__in UINT uiCodepage
	)
{
	Assert(ppwz && szSource);

	HRESULT hr = S_OK;
	LPWSTR pwz = NULL;
	DWORD_PTR cch = 0;
	DWORD_PTR cchDest = cchSource;  // at least enough

	if (*ppwz)
	{
		cch = MemSize(*ppwz);  // get the count in bytes so we can check if it failed (returns -1)
		if (-1 == cch)
		{
			ExitOnFailure(hr = E_INVALIDARG, "failed to get size of destination string");
		}
		cch /= sizeof(WCHAR);  //convert the count in bytes to count in characters
	}

	if (0 == cchSource)
	{
		cchDest = ::MultiByteToWideChar(uiCodepage, 0, szSource, -1, NULL, 0);
		if (0 == cchDest)
		{
			ExitWithLastError1(hr, "failed to get required size for conversion to unicode: %s", szSource);
		}

		--cchDest; //subtract one because MultiByteToWideChar includes space for the NULL terminator that we track below
	}
	else if (L'\0' == szSource[cchSource]) // if the source already had a null terminator, don't count that in the character count because we track it below
	{
		cchDest = cchSource - 1;
	}

	if (cch < cchDest + 1)
	{
		cch = cchDest + 1;
		if (cch >= MAXDWORD / sizeof(WCHAR))
		{
			ExitOnFailure1(hr = E_OUTOFMEMORY, "Not enough memory to allocate string of size: %d", cch);
		}

		if (*ppwz)
		{
			pwz = static_cast<LPWSTR>(MemReAlloc(*ppwz, sizeof(WCHAR) * cch, TRUE));
		}
		else
		{
			pwz = static_cast<LPWSTR>(MemAlloc(sizeof(WCHAR) * cch, TRUE));
		}

		ExitOnNull1(pwz, hr, E_OUTOFMEMORY, "failed to allocate string, len: %d", cch);

		*ppwz = pwz;
	}

	if (0 == ::MultiByteToWideChar(uiCodepage, 0, szSource, 0 == cchSource ? -1 : (int)cchSource, *ppwz, (int)cch))
	{
		ExitWithLastError1(hr, "failed to convert to unicode: %s", szSource);
	}
	(*ppwz)[cchDest] = L'\0';

LExit:
	return hr;
}
Ejemplo n.º 4
0
/********************************************************************
 CabOperation - helper function that enumerates or extracts files
                   from cabinet

 NOTE: wzCabinet must be full path to cabinet file
       wzExtractFile can be a single file id or "*" to extract all files
       wzExttractDir must be normalized (end in a "\")
       if pfnBeginFile is NULL pfnEndFile must be NULL and vice versa
       pfnNotify is callback function to get notified for each file
       in the cabinet. If it's NULL, files will be extracted.
********************************************************************/
static HRESULT DAPI CabOperation(
    __in LPCWSTR wzCabinet,
    __in LPCWSTR wzExtractFile,
    __in_opt LPCWSTR wzExtractDir,
    __in_opt CAB_CALLBACK_PROGRESS pfnProgress,
    __in_opt LPVOID pvContext,
    __in_opt STDCALL_PFNFDINOTIFY pfnNotify,
    __in DWORD64 dw64EmbeddedOffset
    )
{
    HRESULT hr = S_OK;
    BOOL fResult;

    LPWSTR sczCabinet = NULL;
    LPWSTR pwz = NULL;
    CHAR szCabDirectory[MAX_PATH * 4]; // Make sure these are big enough for UTF-8 strings
    CHAR szCabFile[MAX_PATH * 4];

    CAB_CALLBACK_STRUCT ccs;
    PFNFDINOTIFY pfnFdiNotify;

    //
    // ensure the cabinet.dll is loaded
    //
    if (!vhfdi)
    {
        hr = LoadCabinetDll();
        ExitOnFailure(hr, "failed to load CABINET.DLL");
    }

    hr = StrAllocString(&sczCabinet, wzCabinet, 0);
    ExitOnFailure1(hr, "Failed to make copy of cabinet name:%ls", wzCabinet);

    //
    // split the cabinet full path into directory and filename and convert to multi-byte (ick!)
    //
    pwz = FileFromPath(sczCabinet);
    ExitOnNull1(pwz, hr, E_INVALIDARG, "failed to process cabinet path: %ls", wzCabinet);

    if (!::WideCharToMultiByte(CP_UTF8, 0, pwz, -1, szCabFile, countof(szCabFile), NULL, NULL))
    {
        ExitWithLastError1(hr, "failed to convert cabinet filename to ASCII: %ls", pwz);
    }

    *pwz = '\0';

    // If a full path was not provided, use the relative current directory.
    if (wzCabinet == pwz)
    {
        hr = ::StringCchCopyA(szCabDirectory, countof(szCabDirectory), ".\\");
        ExitOnFailure(hr, "Failed to copy relative current directory as cabinet directory.");
    }
    else
    {
        if (!::WideCharToMultiByte(CP_UTF8, 0, sczCabinet, -1, szCabDirectory, countof(szCabDirectory), NULL, NULL))
        {
            ExitWithLastError1(hr, "failed to convert cabinet directory to ASCII: %ls", sczCabinet);
        }
    }

    //
    // iterate through files in cabinet extracting them to the callback function
    //
    ccs.fStopExtracting = FALSE;
    ccs.pwzExtract = wzExtractFile;
    ccs.pwzExtractDir = wzExtractDir;
    ccs.pfnProgress = pfnProgress;
    ccs.pvContext = pvContext;

    vdw64EmbeddedOffset = dw64EmbeddedOffset;

    // if pfnNotify is given, use it, otherwise use default callback
    if (NULL == pfnNotify)
    {
        pfnFdiNotify = CabExtractCallback; 
    }
    else
    {
        v_pfnNetFx11Notify = pfnNotify;
        pfnFdiNotify = FDINotify;
    }
    fResult = vpfnFDICopy(vhfdi, szCabFile, szCabDirectory, 0, pfnFdiNotify, NULL, static_cast<void*>(&ccs));
    if (!fResult && !ccs.fStopExtracting)   // if something went wrong and it wasn't us just stopping the extraction, then return a failure
    {
        ExitWithLastError1(hr, "failed to extract cabinet file: %ls", sczCabinet);
    }

LExit:
    ReleaseStr(sczCabinet);
    v_pfnNetFx11Notify = NULL;

    return hr;
}