Beispiel #1
0
void testDestEnd(){
    wchar_t dest[11];
    wchar_t * destEnd;

    diag("Test calculation of destEnd.");

    ok(SUCCEEDED(StringCbPrintfExW(dest, 11 * sizeof(wchar_t),
                    &destEnd, NULL, 0, L"Data")),
            "Test calculation of destEnd "
            "while printing short string.");
    is_wstring(L"Data", dest,
            "Result of printing short string.");
    ok(destEnd == &dest[4],
            "Value of destEnd after printing short string.");

    ok(SUCCEEDED(StringCbPrintfExW(dest, 11 * sizeof(wchar_t),
                    &destEnd, NULL, 0, L"")),
            "Test calculation of destEnd "
            "while printing empty string.");
    is_wstring(L"", dest,
            "Result of printing empty string.");
    ok(destEnd == &dest[0],
            "Value of destEnd after printing empty string.");

    ok(StringCbPrintfExW(dest, 11 * sizeof(wchar_t), &destEnd,
                NULL, 0, L"longer %ls", L"string") ==
            STRSAFE_E_INSUFFICIENT_BUFFER,
            "Test calculation of destEnd "
            "while printing a too long string.");
    is_wstring(L"longer str", dest,
            "Result of printing a too long string.");
    ok(destEnd == &dest[10],
            "Value of destEnd after printing a too long string.");
}
Beispiel #2
0
void testRemaining(){
    wchar_t dest[11];
    size_t remaining;

    diag("Test calculation of remaining space.");

    ok(SUCCEEDED(StringCbPrintfExW(dest, 11 * sizeof(wchar_t),
                    NULL, &remaining, 0, L"STR")),
            "Test calculation of remaining space "
            "while printing short string.");
    is_wstring(L"STR", dest,
            "Result of printing short string.");
    is_int(8 * sizeof(wchar_t), remaining,
            "Number of remaining characters after printing short string.");

    ok(SUCCEEDED(StringCbPrintfExW(dest, 11 * sizeof(wchar_t),
                    NULL, &remaining, 0, L"")),
            "Test calculation of remaining space "
            "while printing empty string.");
    is_wstring(L"", dest,
            "Result of printing empty string.");
    is_int(11 * sizeof(wchar_t), remaining,
            "Number of remaining characters after printing empty string.");

    ok(StringCbPrintfExW(dest, 11 * sizeof(wchar_t),
                NULL, &remaining, 0, L"too long string") ==
            STRSAFE_E_INSUFFICIENT_BUFFER,
            "Test calculation of remaining space "
            "while printing a too long string.");
    is_wstring(L"too long s", dest,
            "Result of printing a too long string.");
    is_int(1 * sizeof(wchar_t), remaining,
            "Number of remaining characters after printing "
            "a too long string.");
}
Beispiel #3
0
static VOID
pLoadImageFromNode(SHIMGVW_FILENODE *node, HWND hwnd)
{
    WCHAR szTitleBuf[800];
    WCHAR szResStr[512];
    WCHAR *c;

    if (node)
    {
        c = wcsrchr(node->FileName, '\\');
        if (c)
        {
            c++;
        }
        
        LoadStringW(hInstance, IDS_APPTITLE, szResStr, 512);
        StringCbPrintfExW(szTitleBuf, 800, NULL, NULL, 0, L"%ls%ls%ls", szResStr, L" - ", c);
        SetWindowTextW(hwnd, szTitleBuf);

        if (image)
        {
            GdipDisposeImage(image);
        }

        pLoadImage(node->FileName);
        InvalidateRect(hDispWnd, NULL, TRUE);
        UpdateWindow(hDispWnd);
    }
}
Beispiel #4
0
int main(void){
    wchar_t dest[11];
    
    plan(31);

    ok(SUCCEEDED(StringCbPrintfExW(dest, 11 * sizeof(wchar_t),
                    NULL, NULL, 0, L"test")),
            "Print short string without any extended functionality.");
    is_wstring(L"test", dest,
            "Result of printing short string.");

    testDestEnd();
    testRemaining();
    testFlags();

    return 0;
}
Beispiel #5
0
static void pSaveImageAs(HWND hwnd)
{
    OPENFILENAMEW sfn;
    ImageCodecInfo *codecInfo;
    WCHAR szSaveFileName[MAX_PATH];
    WCHAR *szFilterMask;
    GUID rawFormat;
    UINT num;
    UINT size;
    UINT sizeRemain;
    UINT j;
    WCHAR *c;

    GdipGetImageEncodersSize(&num, &size);
    codecInfo = malloc(size);
    if (!codecInfo)
    {
        DPRINT1("malloc() failed in pSaveImageAs()\n");
        return;
    }

    GdipGetImageEncoders(num, size, codecInfo);
    GdipGetImageRawFormat(image, &rawFormat);

    sizeRemain = 0;

    for (j = 0; j < num; ++j)
    {
        // Every pair needs space for the Description, twice the Extensions, 1 char for the space, 2 for the braces and 2 for the NULL terminators.
        sizeRemain = sizeRemain + (((wcslen(codecInfo[j].FormatDescription) + (wcslen(codecInfo[j].FilenameExtension) * 2) + 5) * sizeof(WCHAR)));
    }

    /* Add two more chars for the last terminator */
    sizeRemain = sizeRemain + (sizeof(WCHAR) * 2);

    szFilterMask = malloc(sizeRemain);
    if (!szFilterMask)
    {
        DPRINT1("cannot allocate memory for filter mask in pSaveImageAs()");
        free(codecInfo);
        return;
    }

    ZeroMemory(szSaveFileName, sizeof(szSaveFileName));
    ZeroMemory(szFilterMask, sizeRemain);
    ZeroMemory(&sfn, sizeof(sfn));
    sfn.lStructSize = sizeof(sfn);
    sfn.hwndOwner   = hwnd;
    sfn.hInstance   = hInstance;
    sfn.lpstrFile   = szSaveFileName;
    sfn.lpstrFilter = szFilterMask;
    sfn.nMaxFile    = MAX_PATH;
    sfn.Flags       = OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY;

    c = szFilterMask;

    for (j = 0; j < num; ++j)
    {
        StringCbPrintfExW(c, sizeRemain, &c, &sizeRemain, 0, L"%ls (%ls)", codecInfo[j].FormatDescription, codecInfo[j].FilenameExtension);

        /* Skip the NULL character */
        c++;
        sizeRemain -= sizeof(*c);

        StringCbPrintfExW(c, sizeRemain, &c, &sizeRemain, 0, L"%ls", codecInfo[j].FilenameExtension);

        /* Skip the NULL character */
        c++;
        sizeRemain -= sizeof(*c);

        if (IsEqualGUID(&rawFormat, &codecInfo[j].FormatID) == TRUE)
        {
            sfn.nFilterIndex = j + 1;
        }
    }

    if (GetSaveFileNameW(&sfn))
    {
        if (GdipSaveImageToFile(image, szSaveFileName, &codecInfo[sfn.nFilterIndex - 1].Clsid, NULL) != Ok)
        {
            DPRINT1("GdipSaveImageToFile() failed\n");
        }
    }

    free(szFilterMask);
    free(codecInfo);
}
Beispiel #6
0
static SHIMGVW_FILENODE*
pBuildFileList(LPWSTR szFirstFile)
{
    HANDLE hFindHandle;
    WCHAR *extension;
    WCHAR szSearchPath[MAX_PATH];
    WCHAR szSearchMask[MAX_PATH];
    WCHAR szFileTypes[MAX_PATH];
    WIN32_FIND_DATAW findData;
    SHIMGVW_FILENODE *currentNode;
    SHIMGVW_FILENODE *root;
    SHIMGVW_FILENODE *conductor;
    ImageCodecInfo *codecInfo;
    UINT num;
    UINT size;
    UINT j;


    wcscpy(szSearchPath, szFirstFile);
    PathRemoveFileSpecW(szSearchPath);

    GdipGetImageDecodersSize(&num, &size);
    codecInfo = malloc(size);
    if (!codecInfo)
    {
        DPRINT1("malloc() failed in pLoadFileList()\n");
        return NULL;
    }

    GdipGetImageDecoders(num, size, codecInfo);

    root = malloc(sizeof(SHIMGVW_FILENODE));
    if (!root)
    {
        DPRINT1("malloc() failed in pLoadFileList()\n");
        free(codecInfo);
        return NULL;
    }

    conductor = root;

    for (j = 0; j < num; ++j)
    {
        StringCbPrintfExW(szFileTypes, MAX_PATH, NULL, NULL, 0, L"%ls", codecInfo[j].FilenameExtension);
        
        extension = wcstok(szFileTypes, L";");
        while (extension != NULL)
        {
            StringCbPrintfExW(szSearchMask, MAX_PATH, NULL, NULL, 0, L"%ls%ls%ls", szSearchPath, L"\\", extension);

            hFindHandle = FindFirstFileW(szSearchMask, &findData);
            if (hFindHandle != INVALID_HANDLE_VALUE)
            {
                do
                {
                    StringCbPrintfExW(conductor->FileName, MAX_PATH, NULL, NULL, 0, L"%ls%ls%ls", szSearchPath, L"\\", findData.cFileName);

                    // compare the name of the requested file with the one currently found.
                    // if the name matches, the current node is returned by the function.
                    if (wcscmp(szFirstFile, conductor->FileName) == 0)
                    {
                        currentNode = conductor;
                    }

                    conductor->Next = malloc(sizeof(SHIMGVW_FILENODE));

                    // if malloc fails, make circular what we have and return it
                    if (!conductor->Next)
                    {
                        DPRINT1("malloc() failed in pLoadFileList()\n");
                        
                        conductor->Next = root;
                        root->Prev = conductor;

                        FindClose(hFindHandle);
                        free(codecInfo);
                        return conductor;
                    }

                    conductor->Next->Prev = conductor;
                    conductor = conductor->Next;
                }
                while (FindNextFileW(hFindHandle, &findData) != 0);

                FindClose(hFindHandle);
            }

            extension = wcstok(NULL, L";");
        }
    }

    // we now have a node too much in the list. In case the requested file was not found,
    // we use this node to store the name of it, otherwise we free it.
    if (currentNode == NULL)
    {
        StringCbPrintfExW(conductor->FileName, MAX_PATH, NULL, NULL, 0, L"%ls", szFirstFile);
        currentNode = conductor;
    }
    else
    {
        conductor = conductor->Prev;
        free(conductor->Next);
    }

    // link the last node with the first one to make the list circular
    conductor->Next = root;
    root->Prev = conductor;
    conductor = currentNode;

    free(codecInfo);

    return conductor;
}
Beispiel #7
0
void testFlags(){
    wchar_t dest[11];
    wchar_t * wanted;

    diag("Test the STRSAFE_IGNORE_NULLS flag.");

    ok(SUCCEEDED(StringCbPrintfExW(dest, 11 * sizeof(wchar_t),
                    NULL, NULL, STRSAFE_IGNORE_NULLS, NULL)),
            "Test printing a NULL string.");
    is_wstring(L"", dest,
            "Result of printing a NULL string.");

    diag("Test the STRSAFE_FILL_BEHIND_NULL flag.");

    ok(SUCCEEDED(StringCbPrintfExW(dest, 11 * sizeof(wchar_t),
                    NULL, NULL, STRSAFE_FILL_BEHIND_NULL | '@',
                    L"testing")),
            "Test filling with '@' behind null termination.");
    is_wstring(L"testing", dest,
            "Result of printing and filling behind null termination.");

    wanted = malloc(3 * sizeof(wchar_t));
    if(wanted == NULL){
        bail("Memory allocation failed.");
    }
    memset(wanted, '@', 3 * sizeof(wchar_t));

    ok(memcmp(&dest[8], wanted, 3 * sizeof(wchar_t)) == 0,
            "Correct data filled after null termination.");

    free(wanted);

    diag("Test the STRSAFE_FILL_ON_FAILURE flag.");

    ok(FAILED(StringCbPrintfExW(dest, 11 * sizeof(wchar_t), NULL, NULL,
                    STRSAFE_FILL_ON_FAILURE | '@', L"too much data")),
            "Test filling with '@' on failure.");

    wanted = malloc(11 * sizeof(wchar_t));
    if(wanted == NULL){
        bail("Memory allocation failed.");
    }
    memset(wanted, '@', 10 * sizeof(wchar_t));
    wanted[10] = L'\0';

    ok(memcmp(dest, wanted, 11 * sizeof(wchar_t)) == 0,
            "Result of filling with '@' on failure.");

    free(wanted);

    diag("Test the STRSAFE_NULL_ON_FAILURE flag.");

    ok(FAILED(StringCbPrintfExW(dest, 11 * sizeof(wchar_t), NULL, NULL,
                    STRSAFE_NULL_ON_FAILURE, L"Also too much")),
            "Test nulling string on failure.");
    is_wstring(L"", dest,
            "Result when nulling string on failure.");

    diag("Test the STRSAFE_NO_TRUNCATION flag.");

    ok(FAILED(StringCbPrintfExW(dest, 11 * sizeof(wchar_t), NULL, NULL,
                    STRSAFE_NO_TRUNCATION, L"Won't fit in dest")),
            "Test printing with truncating disabled.");
    is_wstring(L"", dest,
            "Result after printing with truncating disabled.");
}
int vswprintfex( wchar_t *buffer, int buffersize, const wchar_t *format, va_list argList )
{
	int ptr=0;
	const wchar_t* in=format;
	LPWSTR end;

	int nNextArg=0,index,length;

    while (*in!='\0')
	{
		if (*in=='%')
		{
			in++;
			
			// Finding first non number
			for(index=0;in[index]>=L'0' && in[index]<=L'9';index++);

			// Now index points to nonnumberic character
			if (in[index]==L':')
			{
				// ok number was argument place
				if (index==0)
					return 0;
				nNextArg=_wtoi(in);
                
				// finding next '%'
				in+=index+1;
				for (length=0;in[length]!=L'\0' && in[length]!=L'%';length++);

				wchar_t* pTemp=new wchar_t[length+2];
				pTemp[0]=L'%';
				MemCopyW(pTemp+1,in,length);
				pTemp[length+1]=L'\0';
				HRESULT hRes=StringCbPrintfExW(buffer+ptr,(buffersize-ptr)*sizeof(wchar_t),&end,
					NULL,STRSAFE_IGNORE_NULLS,pTemp,va_getarg(argList,nNextArg));
				if (FAILED(hRes))
					return 0;
                ptr=int(end-buffer);
				delete[] pTemp;

				if (in[length]==L'\0')
					break;
				
				in+=length;
			}
			else
			{
				nNextArg++;
				for (;in[index]!=L'\0' && in[index]!=L'%';index++);
			

				wchar_t* pTemp=new wchar_t[index+2];
				pTemp[0]='%';
				MemCopyW(pTemp+1,in,index);
				pTemp[index+1]=L'\0';
				
                
				HRESULT hRes=StringCbPrintfExW(buffer+ptr,(buffersize-ptr)*sizeof(wchar_t),&end,
					NULL,STRSAFE_IGNORE_NULLS,pTemp,va_getarg(argList,nNextArg));
				if (FAILED(hRes))
					return 0;
                ptr=int(end-buffer);

				delete[] pTemp;
				
				if (in[index]==L'\0')
					break;
				
				in+=index;                
			}
		}
		else
			buffer[ptr++]=*(in++);
	}
	buffer[ptr]='\0';
	return ptr;
}
Beispiel #9
0
VOID __fastcall HashSaveWorkerMain( PHASHSAVECONTEXT phsctx )
{
	// Note that ALL message communication to and from the main window MUST
	// be asynchronous, or else there may be a deadlock.

	// Prep: expand directories, max path, etc. (prefix was set by earlier call)
	PostMessage(phsctx->hWnd, HM_WORKERTHREAD_TOGGLEPREP, (WPARAM)phsctx, TRUE);
	if (! HashCalcPrepare(phsctx))
        return;
    HashCalcSetSaveFormat(phsctx);
	PostMessage(phsctx->hWnd, HM_WORKERTHREAD_TOGGLEPREP, (WPARAM)phsctx, FALSE);

    // Extract the slist into a vector for parallel_for_each
    std::vector<PHASHSAVEITEM> vecpItems;
    vecpItems.resize(phsctx->cTotal + 1);
    SLBuildIndex(phsctx->hList, (PVOID*)vecpItems.data());
    assert(vecpItems.back() == nullptr);
    vecpItems.pop_back();
    assert(vecpItems.back() != nullptr);

#ifdef USE_PPL
    const bool bMultithreaded = vecpItems.size() > 1 && IsSSD(vecpItems[0]->szPath);
    concurrency::concurrent_vector<void*> vecBuffers;  // a vector of all allocated read buffers (one per thread)
    DWORD dwBufferTlsIndex = TlsAlloc();               // TLS index of the current thread's read buffer
    if (dwBufferTlsIndex == TLS_OUT_OF_INDEXES)
        return;
#else
    constexpr bool bMultithreaded = false;
#endif

    PBYTE pbTheBuffer;  // file read buffer, used iff not multithreaded
    if (! bMultithreaded)
    {
        pbTheBuffer = (PBYTE)VirtualAlloc(NULL, READ_BUFFER_SIZE, MEM_COMMIT, PAGE_READWRITE);
        if (pbTheBuffer == NULL)
            return;
    }

    // Initialize the progress bar update synchronization vars
    CRITICAL_SECTION updateCritSec;
    volatile ULONGLONG cbCurrentMaxSize = 0;
    if (bMultithreaded)
        InitializeCriticalSection(&updateCritSec);

#ifdef _TIMED
    DWORD dwStarted;
    dwStarted = GetTickCount();
#endif

    class CanceledException {};

    // concurrency::parallel_for_each(vecpItems.cbegin(), vecpItems.cend(), ...
    auto per_file_worker = [&](PHASHSAVEITEM pItem)
	{
        WHCTXEX whctx;

        // Indicate which hash type we are after, see WHEX... values in WinHash.h
        whctx.dwFlags = 1 << (phsctx->ofn.nFilterIndex - 1);

        PBYTE pbBuffer;
#ifdef USE_PPL
        if (bMultithreaded)
        {
            // Allocate or retrieve the already-allocated read buffer for the current thread
            pbBuffer = (PBYTE)TlsGetValue(dwBufferTlsIndex);
            if (pbBuffer == NULL)
            {
                pbBuffer = (PBYTE)VirtualAlloc(NULL, READ_BUFFER_SIZE, MEM_COMMIT, PAGE_READWRITE);
                if (pbBuffer == NULL)
                    throw CanceledException();
                // Cache the read buffer for the current thread
                vecBuffers.push_back(pbBuffer);
                TlsSetValue(dwBufferTlsIndex, pbBuffer);
            }
        }
#endif

#pragma warning(push)
#pragma warning(disable: 4700 4703)  // potentially uninitialized local pointer variable 'pbBuffer' used
		// Get the hash
		WorkerThreadHashFile(
			(PCOMMONCONTEXT)phsctx,
			pItem->szPath,
			&whctx,
			&pItem->results,
            bMultithreaded ? pbBuffer : pbTheBuffer,
			NULL, 0,
            bMultithreaded ? &updateCritSec : NULL, &cbCurrentMaxSize
#ifdef _TIMED
          , &pItem->dwElapsed
#endif
        );

        if (phsctx->status == PAUSED)
            WaitForSingleObject(phsctx->hUnpauseEvent, INFINITE);
		if (phsctx->status == CANCEL_REQUESTED)
            throw CanceledException();

		// Write the data
		HashCalcWriteResult(phsctx, pItem);

		// Update the UI
		InterlockedIncrement(&phsctx->cSentMsgs);
		PostMessage(phsctx->hWnd, HM_WORKERTHREAD_UPDATE, (WPARAM)phsctx, (LPARAM)pItem);
    };
#pragma warning(pop)

    try
    {
#ifdef USE_PPL
        if (bMultithreaded)
            concurrency::parallel_for_each(vecpItems.cbegin(), vecpItems.cend(), per_file_worker);
        else
#endif
            std::for_each(vecpItems.cbegin(), vecpItems.cend(), per_file_worker);
    }
    catch (CanceledException) {}  // ignore cancellation requests

#ifdef _TIMED
    if (phsctx->cTotal > 1 && phsctx->status != CANCEL_REQUESTED)
    {
        union {
            CHAR  szA[MAX_STRINGMSG];
            WCHAR szW[MAX_STRINGMSG];
        } buffer;
        size_t cbBufferLeft;
        if (phsctx->opt.dwSaveEncoding == 1)  // UTF-16
        {
            StringCbPrintfExW(buffer.szW, sizeof(buffer), NULL, &cbBufferLeft, 0, L"; Total elapsed: %d ms\r\n", GetTickCount() - dwStarted);
        }
        else                                  // UTF-8 or ANSI
        {
            StringCbPrintfExA(buffer.szA, sizeof(buffer), NULL, &cbBufferLeft, 0,  "; Total elapsed: %d ms\r\n", GetTickCount() - dwStarted);
        }
        DWORD dwUnused;
        WriteFile(phsctx->hFileOut, buffer.szA, (DWORD) (sizeof(buffer) - cbBufferLeft), &dwUnused, NULL);
    }
#endif

#ifdef USE_PPL
    if (bMultithreaded)
    {
        for (void* pBuffer : vecBuffers)
            VirtualFree(pBuffer, 0, MEM_RELEASE);
        DeleteCriticalSection(&updateCritSec);
    }
    else
#endif
        VirtualFree(pbTheBuffer, 0, MEM_RELEASE);
}