Example #1
0
//
// Description:
//  Converts a BSTR array in a VARIANT to an equivalent array of PWSTRs.
//
// Parameters:
//  vtStringArray - A string array stored in a VARIANT that wraps a SAFEARRAY.
//
//  pppWstrArray - On success, receives an array of PWSTR* populated with the
//      values from vtStringArray represented as PWSTRs. Caller must free with
//      HB_SAFE_FREE_ARRAY.
//
//  pcWstrArray - On success, is set to the number of elements in pppWstrArray.
//
HRESULT VariantStringArrayToWstrArray(__in VARIANT vtStringArray, __out PWSTR** pppWstrArray, __out size_t* pcWstrArray)
{
    HRESULT hr;
    SAFEARRAY* arrStrings;
    size_t cWstrArrayLocal = 0;
    size_t cbWstrArrayLocal;
    PWSTR* ppWstrArrayLocal = NULL;
    BSTR bstrCurrent;

    arrStrings = vtStringArray.parray;

    cWstrArrayLocal = arrStrings->rgsabound[0].cElements;

    hr = SizeTMult(cWstrArrayLocal, sizeof(PWSTR*), &cbWstrArrayLocal);
    if(HB_FAILED(hr)) {
        goto cleanexit;
    }

    ppWstrArrayLocal = (PWSTR*)malloc(cbWstrArrayLocal);
    if(!ppWstrArrayLocal) {
        hr = E_OUTOFMEMORY;
        goto cleanexit;
    }

    //
    // Zero out the array so that elements can be safely deleted if
    // initialization partway through.
    //

    memset(ppWstrArrayLocal, 0, cbWstrArrayLocal);

    for(size_t stringIndex = 0; stringIndex < cWstrArrayLocal; stringIndex++) {
        bstrCurrent = ((BSTR*)arrStrings->pvData)[stringIndex];
        hr = BStrToPWchar(bstrCurrent, &ppWstrArrayLocal[stringIndex]);
        if(HB_FAILED(hr)) {
            goto cleanexit;
        }
    }

    *pppWstrArray = ppWstrArrayLocal;
    ppWstrArrayLocal = NULL;

    *pcWstrArray = cWstrArrayLocal;
    cWstrArrayLocal = 0;

cleanexit:
    HB_SAFE_FREE_ARRAY(ppWstrArrayLocal, cWstrArrayLocal);

    return hr;
}
Example #2
0
//
// Description:
//  Converts a BSTR to an equivalent PWSTR.
//
// Parameters:
//  bstr - A string represented as a BSTR.
//
//  ppWStr - On success, is set to the PWSTR equivalent of bstr. Caller must
//      free with HB_SAFE_FREE.
//
HRESULT BStrToPWchar(__in BSTR bstr, __out PWSTR* ppWStr)
{
    HRESULT hr;
    size_t cbWStr;
    PWSTR pWStrLocal = NULL;

    hr = SizeTMult(SysStringLen(bstr), sizeof(WCHAR), &cbWStr);
    if(HB_FAILED(hr)) {
        goto cleanexit;
    }

    //
    // Correct for additional NULL pointer
    //

    hr = SizeTAdd(cbWStr, sizeof(WCHAR), &cbWStr);
    if(HB_FAILED(hr)) {
        goto cleanexit;
    }

    pWStrLocal = (PWSTR)malloc(cbWStr);
    if(!pWStrLocal) {
        hr = E_OUTOFMEMORY;
        goto cleanexit;
    }

    hr =  StringCbCopy(pWStrLocal, cbWStr, static_cast<wchar_t*>(bstr));
    if(HB_FAILED(hr)) {
        goto cleanexit;
    }

    *ppWStr = pWStrLocal;
    pWStrLocal = NULL;

cleanexit:
    HB_SAFE_FREE(pWStrLocal);

    return hr;
}
Example #3
0
//
// Description:
//  Retrieves that the service manage uses to launch the YoNTMA binary as a
//  service.
//
// Parameters:
//  ppszServiceExecutionString - On success, contains the command line string
//      used to launch YoNTMA (including arguments). Caller must free with
//      HB_SAFE_FREE.
//
HRESULT GetServiceExecutionString(__out PTSTR* ppszServiceExecutionString)
{
    HRESULT hr;
    DWORD rc;
    SC_HANDLE hService = NULL;
    LPQUERY_SERVICE_CONFIG pQueryServiceConfig = NULL;
    DWORD cbQueryServiceConfig;
    DWORD cbQueryServiceConfigRequired;
    PTSTR pszServiceExecutionStringLocal = NULL;
    size_t cchServiceExecutionStringLocal;
    size_t cbServiceExecutionStringLocal;

    hr = OpenYontmaService(&hService);
    if(HB_FAILED(hr)) {
        goto cleanexit;
    }

    QueryServiceConfig(hService,
                       NULL,
                       0,
                       &cbQueryServiceConfigRequired);

    rc = GetLastError();

    //
    // QueryServiceConfig succeeded with a zero-sized buffer? Something is wrong.
    //

    if(rc == ERROR_SUCCESS) {
        hr = E_UNEXPECTED;
        goto cleanexit;
    }
    else if(rc != ERROR_INSUFFICIENT_BUFFER) {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto cleanexit;
    }

    cbQueryServiceConfig = cbQueryServiceConfigRequired;
    pQueryServiceConfig = (LPQUERY_SERVICE_CONFIG)LocalAlloc(LMEM_FIXED, cbQueryServiceConfig);
    if(!pQueryServiceConfig) {
        hr = E_OUTOFMEMORY;
        goto cleanexit;
    }

    if(!QueryServiceConfig(hService,
                           pQueryServiceConfig,
                           cbQueryServiceConfig,
                           &cbQueryServiceConfigRequired)) {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto cleanexit;
    }

    cchServiceExecutionStringLocal = _tcslen(pQueryServiceConfig->lpBinaryPathName);
    hr = SizeTAdd(cchServiceExecutionStringLocal,
                  1,
                  &cchServiceExecutionStringLocal);
    if(HB_FAILED(hr)) {
        goto cleanexit;
    }

    hr = SizeTMult(cchServiceExecutionStringLocal, sizeof(TCHAR), &cbServiceExecutionStringLocal);
    if(HB_FAILED(hr)) {
        goto cleanexit;
    }

    pszServiceExecutionStringLocal = (PTSTR)malloc(cbServiceExecutionStringLocal);
    if(!pszServiceExecutionStringLocal) {
        hr = E_OUTOFMEMORY;
        goto cleanexit;
    }

    hr = StringCchCopy(pszServiceExecutionStringLocal,
                       cchServiceExecutionStringLocal,
                       pQueryServiceConfig->lpBinaryPathName);
    if(HB_FAILED(hr)) {
        goto cleanexit;
    }

    *ppszServiceExecutionString = pszServiceExecutionStringLocal;
    pszServiceExecutionStringLocal = NULL;

cleanexit:
    HB_SAFE_CLOSE_SERVICE_HANDLE(hService);
    HB_SAFE_LOCAL_FREE(pQueryServiceConfig);
    HB_SAFE_FREE(pszServiceExecutionStringLocal);

    return hr;
}
Example #4
0
/*++
*******************************************************************
    E n u m P r i n t P r o c e s s o r D a t a t y p e s W

    Routine Description:
        Enumerates the data types supported by the print processor.

    Arguments:
        pName               => server name
        pPrintProcessorName => print processor name
        Level               => level of data to return (must be 1)
        pDatatypes          => structure array to fill in
        cbBuf               => length of structure array in bytes
        pcbNeeded           => buffer length copied/required
        pcReturned          => number of structures returned

    Return Value:
        TRUE  if successful
        FALSE if failed - caller must use GetLastError for reason
*******************************************************************
--*/
_Use_decl_annotations_
BOOL WINAPI
EnumPrintProcessorDatatypes(
    LPWSTR  pName,
    LPWSTR  pPrintProcessorName,
    DWORD   Level,
    LPBYTE  pDatatypes,
    DWORD   cbBuf,
    LPDWORD pcbNeeded,
    LPDWORD pcReturned
)
{
    DATATYPES_INFO_1    *pInfo1 = (DATATYPES_INFO_1 *)pDatatypes;
    LPWSTR              *pMyDatatypes = Datatypes;
    size_t              cbTotal=0;
    ULONG               cchBuf =0;
    LPBYTE              pEnd;
    BOOL                bRetVal = TRUE;
    HRESULT             hr;
    size_t              tempSizeT;

    UNREFERENCED_PARAMETER(pName);
    UNREFERENCED_PARAMETER(pPrintProcessorName);

    if ( NULL == pcbNeeded  ||
         NULL == pcReturned )
    {
        SetLastError (ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    /** Start assuming failure, no entries returned **/

    *pcbNeeded  = 0;
    *pcReturned = 0;

    if (Level != 1)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    /** Add up the minimum buffer required **/

    while (*pMyDatatypes) {
        if (FAILED(SizeTMult(wcslen(*pMyDatatypes), sizeof(WCHAR), &tempSizeT)) ||
            FAILED(SizeTAdd(tempSizeT, sizeof(WCHAR), &tempSizeT)) ||
            FAILED(SizeTAdd(tempSizeT, sizeof(DATATYPES_INFO_1), &tempSizeT)) ||
            FAILED(SizeTAdd(cbTotal, tempSizeT, &cbTotal)))
        {
            SetLastError (ERROR_ARITHMETIC_OVERFLOW);
            bRetVal = FALSE;
            break;
        }

        pMyDatatypes++;
    }

    /** Set the buffer length returned/required **/

    if (bRetVal && FAILED(SizeTToDWord(cbTotal, pcbNeeded)))
    {
        SetLastError (ERROR_ARITHMETIC_OVERFLOW);
        bRetVal = FALSE;
    }

    /** Fill in the array only if there is sufficient space **/

    if (bRetVal && cbTotal <= cbBuf)
    {

        if ( NULL == pInfo1 ) //pInfo1 is same as pDatatypes
        {
            SetLastError (ERROR_INVALID_PARAMETER);
            bRetVal = FALSE;
        }
        else
        {

            /** Pick up pointer to end of the given buffer **/

            pEnd = (LPBYTE)pInfo1 + cbBuf;


            /** Pick up our list of supported data types **/

            pMyDatatypes = Datatypes;

            /**
                Fill in the given buffer.  We put the data names at the end of
                the buffer, working towards the front.  The structures are put
                at the front, working towards the end.
            **/

            while (*pMyDatatypes) {

                if (FAILED(SizeTAdd(wcslen(*pMyDatatypes), 1, &tempSizeT)) || //+1 is for \0.
                    FAILED(SizeTToDWord(tempSizeT, &cchBuf)))
                {
                    SetLastError (ERROR_ARITHMETIC_OVERFLOW);
                    bRetVal = FALSE;
                    break;
                }
                pEnd -= cchBuf*sizeof(WCHAR);

                hr = StringCchCopy ( (LPWSTR)pEnd, cchBuf, *pMyDatatypes);
                if ( FAILED(hr) )
                {
                    //
                    // For the hr values returned by StringCchCopy, the following macro
                    // is sufficient
                    //
                    SetLastError (HRESULT_CODE(hr));
                    bRetVal = FALSE;
                    break;
                }

                pInfo1->pName = (LPWSTR)pEnd;
                pInfo1++;
                (*pcReturned)++;

                pMyDatatypes++;
            }
        }

    } else {

        /** Caller didn't have large enough buffer, set error and return **/

        SetLastError(ERROR_INSUFFICIENT_BUFFER);
        bRetVal = FALSE;
    }

    return bRetVal;
}