Exemple #1
0
/*++
Function:
  GetFullPathNameA

See MSDN doc.
--*/
DWORD
PALAPI
GetFullPathNameA(
     IN LPCSTR lpFileName,
     IN DWORD nBufferLength,
     OUT LPSTR lpBuffer,
     OUT LPSTR *lpFilePart)
{
    DWORD  nReqPathLen, nRet = 0;
    LPSTR lpUnixPath = NULL;
    BOOL fullPath = FALSE;

    PERF_ENTRY(GetFullPathNameA);
    ENTRY("GetFullPathNameA(lpFileName=%p (%s), nBufferLength=%u, lpBuffer=%p, "
          "lpFilePart=%p)\n",
          lpFileName?lpFileName:"NULL",
          lpFileName?lpFileName:"NULL", nBufferLength, lpBuffer, lpFilePart);

    if(NULL == lpFileName)
    {
        WARN("lpFileName is NULL\n");
        SetLastError(ERROR_INVALID_PARAMETER);
        goto done;
    }

    /* find out if lpFileName is a partial or full path */
    if ('\\' == *lpFileName || '/' == *lpFileName)
    {
        fullPath = TRUE;
    }

    if(fullPath)
    {
        lpUnixPath = PAL__strdup( lpFileName );
        if(NULL == lpUnixPath)
        {
            ERROR("strdup() failed; error is %d (%s)\n",
                  errno, strerror(errno));
            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
            goto done;
        }
    }   
    else
    {
        size_t max_len;

        /* allocate memory for full non-canonical path */
        max_len = strlen(lpFileName)+1; /* 1 for the slash to append */
        max_len += MAX_LONGPATH + 1; 
        lpUnixPath = (LPSTR)PAL_malloc(max_len);
        if(NULL == lpUnixPath)
        {
            ERROR("PAL_malloc() failed; error is %d (%s)\n",
                  errno, strerror(errno));
            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
            goto done;
        }
        
        /* build full path */
        if(!GetCurrentDirectoryA(MAX_LONGPATH + 1, lpUnixPath))
        {
            /* no reason for this to fail now... */
            ASSERT("GetCurrentDirectoryA() failed! lasterror is %#xd\n",
                   GetLastError());
            SetLastError(ERROR_INTERNAL_ERROR);
            goto done;
        }
        
        if (strcat_s(lpUnixPath, max_len, "/") != SAFECRT_SUCCESS)
        {
            ERROR("strcat_s failed!\n");
            SetLastError(ERROR_FILENAME_EXCED_RANGE);
            goto done;
        }

        if (strcat_s(lpUnixPath, max_len, lpFileName) != SAFECRT_SUCCESS)
        {
            ERROR("strcat_s failed!\n");
            SetLastError(ERROR_FILENAME_EXCED_RANGE);
            goto done;
        }
    }

    /* do conversion to Unix path */
    FILEDosToUnixPathA( lpUnixPath );
 
    /* now we can canonicalize this */
    FILECanonicalizePath(lpUnixPath);

    /* at last, we can figure out how long this path is */
    nReqPathLen = strlen(lpUnixPath)+1;

    if(nBufferLength < nReqPathLen)
    {
        TRACE("reporting insufficient buffer : minimum is %d, caller "
              "provided %d\n", nReqPathLen, nBufferLength);
        nRet = nReqPathLen;
        goto done;
    }

    nRet = nReqPathLen-1;
    strcpy_s(lpBuffer, nBufferLength, lpUnixPath);

    /* locate the filename component if caller cares */
    if(lpFilePart)
    {
        *lpFilePart = strrchr(lpBuffer, '/');

        if (*lpFilePart == NULL)
        {
            ASSERT("Not able to find '/' in the full path.\n");
            SetLastError( ERROR_INTERNAL_ERROR );
            nRet = 0;
            goto done;
        }
        else 
        {
            (*lpFilePart)++; 
        }
    }

done:
    PAL_free (lpUnixPath);
    LOGEXIT("GetFullPathNameA returns DWORD %u\n", nRet);
    PERF_EXIT(GetFullPathNameA);
    return nRet;
}
Exemple #2
0
bool __cdecl diablo_get_not_running()
{
	SetLastError(0);
	CreateEventA(NULL, FALSE, FALSE, "DiabloEvent");
	return GetLastError() != ERROR_ALREADY_EXISTS;
}
Exemple #3
0
/***********************************************************************
 *		UnMapAndLoad (IMAGEHLP.@)
 */
BOOL WINAPI UnMapAndLoad(PLOADED_IMAGE LoadedImage)
{
  FIXME("(%p): stub\n", LoadedImage);
  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  return FALSE;
}
Exemple #4
0
static void test_string_conversion(LPBOOL bUsedDefaultChar)
{
    char mbc;
    char mbs[15];
    int ret;
    WCHAR wc1 = 228;                           /* Western Windows-1252 character */
    WCHAR wc2 = 1088;                          /* Russian Windows-1251 character not displayable for Windows-1252 */
    static const WCHAR wcs[] = {'T', 'h', 1088, 'i', 0}; /* String with ASCII characters and a Russian character */
    static const WCHAR dbwcs[] = {28953, 25152, 0}; /* String with Chinese (codepage 950) characters */
    static const WCHAR dbwcs2[] = {0x7bb8, 0x3d, 0xc813, 0xac00, 0xb77d, 0};
    static const char default_char[] = {0xa3, 0xbf, 0};

    SetLastError(0xdeadbeef);
    ret = WideCharToMultiByte(1252, 0, &wc1, 1, &mbc, 1, NULL, bUsedDefaultChar);
    ok(ret == 1, "ret is %d\n", ret);
    ok(mbc == '\xe4', "mbc is %d\n", mbc);
    if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
    ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());

    SetLastError(0xdeadbeef);
    ret = WideCharToMultiByte(1252, 0, &wc2, 1, &mbc, 1, NULL, bUsedDefaultChar);
    ok(ret == 1, "ret is %d\n", ret);
    ok(mbc == 63, "mbc is %d\n", mbc);
    if(bUsedDefaultChar) ok(*bUsedDefaultChar == TRUE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
    ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());

    if (IsValidCodePage(1251))
    {
        SetLastError(0xdeadbeef);
        ret = WideCharToMultiByte(1251, 0, &wc2, 1, &mbc, 1, NULL, bUsedDefaultChar);
        ok(ret == 1, "ret is %d\n", ret);
        ok(mbc == '\xf0', "mbc is %d\n", mbc);
        if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
        ok(GetLastError() == 0xdeadbeef ||
           broken(GetLastError() == 0), /* win95 */
           "GetLastError() is %u\n", GetLastError());

        SetLastError(0xdeadbeef);
        ret = WideCharToMultiByte(1251, 0, &wc1, 1, &mbc, 1, NULL, bUsedDefaultChar);
        ok(ret == 1, "ret is %d\n", ret);
        ok(mbc == 97, "mbc is %d\n", mbc);
        if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
        ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
    }
    else
        skip("Codepage 1251 not available\n");

    /* This call triggers the last Win32 error */
    SetLastError(0xdeadbeef);
    ret = WideCharToMultiByte(1252, 0, wcs, -1, &mbc, 1, NULL, bUsedDefaultChar);
    ok(ret == 0, "ret is %d\n", ret);
    ok(mbc == 84, "mbc is %d\n", mbc);
    if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
    ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetLastError() is %u\n", GetLastError());

    SetLastError(0xdeadbeef);
    ret = WideCharToMultiByte(1252, 0, wcs, -1, mbs, sizeof(mbs), NULL, bUsedDefaultChar);
    ok(ret == 5, "ret is %d\n", ret);
    ok(!strcmp(mbs, "Th?i"), "mbs is %s\n", mbs);
    if(bUsedDefaultChar) ok(*bUsedDefaultChar == TRUE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
    ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
    mbs[0] = 0;

    /* WideCharToMultiByte mustn't add any null character automatically.
       So in this case, we should get the same string again, even if we only copied the first three bytes. */
    SetLastError(0xdeadbeef);
    ret = WideCharToMultiByte(1252, 0, wcs, 3, mbs, sizeof(mbs), NULL, bUsedDefaultChar);
    ok(ret == 3, "ret is %d\n", ret);
    ok(!strcmp(mbs, "Th?i"), "mbs is %s\n", mbs);
    if(bUsedDefaultChar) ok(*bUsedDefaultChar == TRUE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
    ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
    ZeroMemory(mbs, 5);

    /* Now this shouldn't be the case like above as we zeroed the complete string buffer. */
    SetLastError(0xdeadbeef);
    ret = WideCharToMultiByte(1252, 0, wcs, 3, mbs, sizeof(mbs), NULL, bUsedDefaultChar);
    ok(ret == 3, "ret is %d\n", ret);
    ok(!strcmp(mbs, "Th?"), "mbs is %s\n", mbs);
    if(bUsedDefaultChar) ok(*bUsedDefaultChar == TRUE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
    ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());

    /* Double-byte tests */
    ret = WideCharToMultiByte(1252, 0, dbwcs, 3, mbs, sizeof(mbs), NULL, bUsedDefaultChar);
    ok(ret == 3, "ret is %d\n", ret);
    ok(!strcmp(mbs, "??"), "mbs is %s\n", mbs);
    if(bUsedDefaultChar) ok(*bUsedDefaultChar == TRUE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);

    ret = WideCharToMultiByte(936, WC_COMPOSITECHECK, dbwcs2, -1, mbs, sizeof(mbs), (const char *)default_char, bUsedDefaultChar);
    ok(ret == 10, "ret is %d\n", ret);
    ok(!strcmp(mbs, "\xf3\xe7\x3d\xa3\xbf\xa3\xbf\xa3\xbf"), "mbs is %s\n", mbs);
    if(bUsedDefaultChar) ok(*bUsedDefaultChar == TRUE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);

    /* Length-only tests */
    SetLastError(0xdeadbeef);
    ret = WideCharToMultiByte(1252, 0, &wc2, 1, NULL, 0, NULL, bUsedDefaultChar);
    ok(ret == 1, "ret is %d\n", ret);
    if(bUsedDefaultChar) ok(*bUsedDefaultChar == TRUE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
    ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());

    SetLastError(0xdeadbeef);
    ret = WideCharToMultiByte(1252, 0, wcs, -1, NULL, 0, NULL, bUsedDefaultChar);
    ok(ret == 5, "ret is %d\n", ret);
    if(bUsedDefaultChar) ok(*bUsedDefaultChar == TRUE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
    ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());

    if (!IsValidCodePage(950))
    {
        skip("Codepage 950 not available\n");
        return;
    }

    /* Double-byte tests */
    SetLastError(0xdeadbeef);
    ret = WideCharToMultiByte(950, 0, dbwcs, -1, mbs, sizeof(mbs), NULL, bUsedDefaultChar);
    ok(ret == 5, "ret is %d\n", ret);
    ok(!strcmp(mbs, "\xb5H\xa9\xd2"), "mbs is %s\n", mbs);
    if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
    ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());

    SetLastError(0xdeadbeef);
    ret = WideCharToMultiByte(950, 0, dbwcs, 1, &mbc, 1, NULL, bUsedDefaultChar);
    ok(ret == 0, "ret is %d\n", ret);
    if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
    ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "GetLastError() is %u\n", GetLastError());
    ZeroMemory(mbs, 5);

    SetLastError(0xdeadbeef);
    ret = WideCharToMultiByte(950, 0, dbwcs, 1, mbs, sizeof(mbs), NULL, bUsedDefaultChar);
    ok(ret == 2, "ret is %d\n", ret);
    ok(!strcmp(mbs, "\xb5H"), "mbs is %s\n", mbs);
    if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
    ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());

    /* Length-only tests */
    SetLastError(0xdeadbeef);
    ret = WideCharToMultiByte(950, 0, dbwcs, 1, NULL, 0, NULL, bUsedDefaultChar);
    ok(ret == 2, "ret is %d\n", ret);
    if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
    ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());

    SetLastError(0xdeadbeef);
    ret = WideCharToMultiByte(950, 0, dbwcs, -1, NULL, 0, NULL, bUsedDefaultChar);
    ok(ret == 5, "ret is %d\n", ret);
    if(bUsedDefaultChar) ok(*bUsedDefaultChar == FALSE, "bUsedDefaultChar is %d\n", *bUsedDefaultChar);
    ok(GetLastError() == 0xdeadbeef, "GetLastError() is %u\n", GetLastError());
}
Exemple #5
0
static void test_utf7_decoding(void)
{
    char input[32];
    WCHAR output[32], expected[32];
    int i, len, expected_len;

    static const signed char base64_decoding_table[] =
    {
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x00-0x0F */
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 0x10-0x1F */
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 0x20-0x2F */
        52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 0x30-0x3F */
        -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, /* 0x40-0x4F */
        15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 0x50-0x5F */
        -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 0x60-0x6F */
        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1  /* 0x70-0x7F */
    };

    struct
    {
        /* inputs */
        char src[32];
        int srclen;
        WCHAR *dst;
        int dstlen;
        /* expected outputs */
        WCHAR expected_dst[32];
        int chars_written;
        int len;
    }
    tests[] =
    {
        /* tests string conversion with srclen=-1 */
        {
            "+T2BZfQ-", -1, output, sizeof(output) / sizeof(WCHAR) - 1,
            {0x4F60,0x597D,0}, 3, 3
        },
        /* tests string conversion with srclen=-2 */
        {
            "+T2BZfQ-", -2, output, sizeof(output) / sizeof(WCHAR) - 1,
            {0x4F60,0x597D,0}, 3, 3
        },
        /* tests string conversion with dstlen=strlen(expected_dst) */
        {
            "+T2BZfQ-", -1, output, 2,
            {0x4F60,0x597D}, 2, 0
        },
        /* tests string conversion with dstlen=strlen(expected_dst)+1 */
        {
            "+T2BZfQ-", -1, output, 3,
            {0x4F60,0x597D,0}, 3, 3
        },
        /* tests string conversion with dstlen=strlen(expected_dst)+2 */
        {
            "+T2BZfQ-", -1, output, 4,
            {0x4F60,0x597D,0}, 3, 3
        },
        /* tests dry run with dst=NULL and dstlen=0 */
        {
            "+T2BZfQ-", -1, NULL, 0,
            {0}, 0, 3
        },
        /* tests dry run with dst!=NULL and dstlen=0 */
        {
            "+T2BZfQ-", -1, output, 0,
            {0}, 0, 3
        },
        /* tests ill-formed UTF-7: 6 bits, not enough for a byte pair */
        {
            "+T-+T-+T-hello", -1, output, sizeof(output) / sizeof(WCHAR) - 1,
            {'h','e','l','l','o',0}, 6, 6
        },
        /* tests ill-formed UTF-7: 12 bits, not enough for a byte pair */
        {
            "+T2-+T2-+T2-hello", -1, output, sizeof(output) / sizeof(WCHAR) - 1,
            {'h','e','l','l','o',0}, 6, 6
        },
        /* tests ill-formed UTF-7: 18 bits, not a multiple of 16 and the last bit is a 1 */
        {
            "+T2B-+T2B-+T2B-hello", -1, output, sizeof(output) / sizeof(WCHAR) - 1,
            {0x4F60,0x4F60,0x4F60,'h','e','l','l','o',0}, 9, 9
        },
        /* tests ill-formed UTF-7: 24 bits, a multiple of 8 but not a multiple of 16 */
        {
            "+T2BZ-+T2BZ-+T2BZ-hello", -1, output, sizeof(output) / sizeof(WCHAR) - 1,
            {0x4F60,0x4F60,0x4F60,'h','e','l','l','o',0}, 9, 9
        },
        /* tests UTF-7 followed by characters that should be encoded but aren't */
        {
            "+T2BZ-\x82\xFE", -1, output, sizeof(output) / sizeof(WCHAR) - 1,
            {0x4F60,0x0082,0x00FE,0}, 4, 4
        },
        /* tests srclen > strlen(src) */
        {
            "a\0b", 4, output, sizeof(output) / sizeof(WCHAR) - 1,
            {'a',0,'b',0}, 4, 4
        },
        /* tests srclen < strlen(src) outside of a UTF-7 sequence */
        {
            "hello", 2, output, sizeof(output) / sizeof(WCHAR) - 1,
            {'h','e'}, 2, 2
        },
        /* tests srclen < strlen(src) inside of a UTF-7 sequence */
        {
            "+T2BZfQ-", 4, output, sizeof(output) / sizeof(WCHAR) - 1,
            {0x4F60}, 1, 1
        },
        /* tests srclen < strlen(src) right at the beginning of a UTF-7 sequence */
        {
            "hi+T2A-", 3, output, sizeof(output) / sizeof(WCHAR) - 1,
            {'h','i'}, 2, 2
        },
        /* tests srclen < strlen(src) right at the end of a UTF-7 sequence */
        {
            "+T2A-hi", 5, output, sizeof(output) / sizeof(WCHAR) - 1,
            {0x4F60}, 1, 1
        },
        /* tests srclen < strlen(src) at the beginning of an escaped + sign */
        {
            "hi+-", 3, output, sizeof(output) / sizeof(WCHAR) - 1,
            {'h','i'}, 2, 2
        },
        /* tests srclen < strlen(src) at the end of an escaped + sign */
        {
            "+-hi", 2, output, sizeof(output) / sizeof(WCHAR) - 1,
            {'+'}, 1, 1
        },
        /* tests len=0 but no error */
        {
            "+", 1, output, sizeof(output) / sizeof(WCHAR) - 1,
            {0}, 0, 0
        },
        /* tests a single null char */
        {
            "", -1, output, sizeof(output) / sizeof(WCHAR) - 1,
            {0}, 1, 1
        },
        /* tests a buffer that runs out while not decoding a UTF-7 sequence */
        {
            "hello", -1, output, 2,
            {'h','e'}, 2, 0
        },
        /* tests a buffer that runs out in the middle of decoding a UTF-7 sequence */
        {
            "+T2BZfQ-", -1, output, 1,
            {0x4F60}, 1, 0
        }
    };

    /* test which one-byte characters remove stray + signs */
    for (i = 0; i < 256; i++)
    {
        sprintf(input, "+%c+AAA", i);

        memset(output, 0x23, sizeof(output) - sizeof(WCHAR));
        output[sizeof(output) / sizeof(WCHAR) - 1] = 0;

        len = MultiByteToWideChar(CP_UTF7, 0, input, 7, output, sizeof(output) / sizeof(WCHAR) - 1);

        if (i == '-')
        {
            /* removes the - sign */
            expected_len = 3;
            expected[0] = 0x002B;
            expected[1] = 0;
            expected[2] = 0;
        }
        else if (i <= 0x7F && base64_decoding_table[i] != -1)
        {
            /* absorbs the character into the base64 sequence */
            expected_len = 2;
            expected[0] = (base64_decoding_table[i] << 10) | 0x03E0;
            expected[1] = 0;
        }
        else
        {
            /* removes the + sign */
            expected_len = 3;
            expected[0] = i;
            expected[1] = 0;
            expected[2] = 0;
        }
        expected[expected_len] = 0x2323;

        ok(len == expected_len, "i=0x%02x: expected len=%i, got len=%i\n", i, expected_len, len);
        ok(memcmp(output, expected, (expected_len + 1) * sizeof(WCHAR)) == 0,
           "i=0x%02x: expected output=%s, got output=%s\n",
           i, wine_dbgstr_wn(expected, expected_len + 1), wine_dbgstr_wn(output, expected_len + 1));
    }

    /* test which one-byte characters terminate a sequence
     * also test whether the unfinished byte pair is discarded or not */
    for (i = 0; i < 256; i++)
    {
        sprintf(input, "+B%c+AAA", i);

        memset(output, 0x23, sizeof(output) - sizeof(WCHAR));
        output[sizeof(output) / sizeof(WCHAR) - 1] = 0;

        len = MultiByteToWideChar(CP_UTF7, 0, input, 8, output, sizeof(output) / sizeof(WCHAR) - 1);

        if (i == '-')
        {
            /* explicitly terminates */
            expected_len = 2;
            expected[0] = 0;
            expected[1] = 0;
        }
        else if (i <= 0x7F)
        {
            if (base64_decoding_table[i] != -1)
            {
                /* absorbs the character into the base64 sequence */
                expected_len = 3;
                expected[0] = 0x0400 | (base64_decoding_table[i] << 4) | 0x000F;
                expected[1] = 0x8000;
                expected[2] = 0;
            }
            else
            {
                /* implicitly terminates and discards the unfinished byte pair */
                expected_len = 3;
                expected[0] = i;
                expected[1] = 0;
                expected[2] = 0;
            }
        }
        else
        {
            /* implicitly terminates but does not the discard unfinished byte pair */
            expected_len = 3;
            expected[0] = i;
            expected[1] = 0x0400;
            expected[2] = 0;
        }
        expected[expected_len] = 0x2323;

        ok(len == expected_len, "i=0x%02x: expected len=%i, got len=%i\n", i, expected_len, len);
        ok(memcmp(output, expected, (expected_len + 1) * sizeof(WCHAR)) == 0,
           "i=0x%02x: expected output=%s, got output=%s\n",
           i, wine_dbgstr_wn(expected, expected_len + 1), wine_dbgstr_wn(output, expected_len + 1));
    }

    for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
    {
        memset(output, 0x23, sizeof(output) - sizeof(WCHAR));
        output[sizeof(output) / sizeof(WCHAR) - 1] = 0;
        SetLastError(0xdeadbeef);

        len = MultiByteToWideChar(CP_UTF7, 0, tests[i].src, tests[i].srclen,
                                  tests[i].dst, tests[i].dstlen);

        tests[i].expected_dst[tests[i].chars_written] = 0x2323;

        if (!tests[i].len && tests[i].chars_written)
        {
            ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
               "tests[%i]: expected error=0x%x, got error=0x%x\n",
               i, ERROR_INSUFFICIENT_BUFFER, GetLastError());
        }
        ok(len == tests[i].len, "tests[%i]: expected len=%i, got len=%i\n", i, tests[i].len, len);

        if (tests[i].dst)
        {
            ok(memcmp(tests[i].dst, tests[i].expected_dst, (tests[i].chars_written + 1) * sizeof(WCHAR)) == 0,
               "tests[%i]: expected dst=%s, got dst=%s\n",
               i, wine_dbgstr_wn(tests[i].expected_dst, tests[i].chars_written + 1),
               wine_dbgstr_wn(tests[i].dst, tests[i].chars_written + 1));
        }
    }
}
Exemple #6
0
static int recycle (const TCHAR *name)
{
	DWORD dirattr = GetFileAttributesSafe (name);
	bool isdir = dirattr != INVALID_FILE_ATTRIBUTES && (dirattr & FILE_ATTRIBUTE_DIRECTORY);
	const TCHAR *namep;
	TCHAR path[MAX_DPATH];
	
	if (currprefs.win32_filesystem_mangle_reserved_names == false) {
		_tcscpy (path, PATHPREFIX);
		_tcscat (path, name);
		namep = path;
	} else {
		namep = name;
	}

	if (currprefs.win32_norecyclebin || isdir || currprefs.win32_filesystem_mangle_reserved_names == false) {
		if (isdir)
			return RemoveDirectory (namep) ? 0 : -1;
		else
			return DeleteFile (namep) ? 0 : -1;
	} else {
		SHFILEOPSTRUCT fos;
		HANDLE h;
		
		h = CreateFile (namep, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
			OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
		if (h != INVALID_HANDLE_VALUE) {
			LARGE_INTEGER size;
			if (GetFileSizeEx (h, &size)) {
				if (size.QuadPart == 0) {
					CloseHandle (h);
					return DeleteFile (namep) ? 0 : -1;
				}
			}
			CloseHandle (h);
		}

		/* name must be terminated by \0\0 */
		TCHAR *p = xcalloc (TCHAR, _tcslen (namep) + 2);
		int v;

		_tcscpy (p, namep);
		memset (&fos, 0, sizeof (fos));
		fos.wFunc = FO_DELETE;
		fos.pFrom = p;
		fos.fFlags = FOF_ALLOWUNDO | FOF_NOCONFIRMATION | FOF_NOERRORUI | FOF_NORECURSION | FOF_SILENT;
		v = SHFileOperation (&fos);
		xfree (p);
		switch (v)
		{
		case 0xb7: //DE_ERROR_MAX
		case 0x7c: //DE_INVALIDFILES
		case 0x402: // "unknown error"
			v = ERROR_FILE_NOT_FOUND;
			break;
		case 0x75: //DE_OPCANCELLED:
		case 0x10000: //ERRORONDEST:
		case 0x78: //DE_ACCESSDENIEDSRC:
		case 0x74: //DE_ROOTDIR:
			v = ERROR_ACCESS_DENIED;
			break;
		}
		SetLastError (v);
		return v ? -1 : 0;
	}
}
Exemple #7
0
// Create an Archive from the specified File List.
VFS_BOOL VFS_Archive_CreateFromFileList( const VFS_String& strArchiveFileName, const VFS_FileNameMap& Files, const VFS_FilterNameList& UsedFilters )
{
    static VFS_BYTE Chunk[ FILE_COPY_CHUNK_SIZE ];

    // If there's already an Archive with the same File Name and it's open...
    VFS_EntityInfo Info;
    if( VFS_Archive_GetInfo( ToLower( strArchiveFileName ), Info ) )
    {
        // Check if the Archive is open.
        if( GetOpenArchives().find( ToLower( Info.strPath ) ) != GetOpenArchives().end() )
        {
            // Check if the Reference Count is != 0.
            if( GetOpenArchives()[ ToLower( Info.strPath ) ]->GetRefCount() > 0 )
            {
                // We don't want to manipulate an open Archive, do we?
                SetLastError( VFS_ERROR_IN_USE );
                return VFS_FALSE;
            }
            else
            {
                // Free the Archive.
                delete GetOpenArchives()[ ToLower( Info.strPath ) ];
                GetOpenArchives().erase( ToLower( Info.strPath ) );
            }
        }
    }
    else
    {
        Info.strPath = ToLower( strArchiveFileName );
        SetLastError( VFS_ERROR_NONE );
    }

    // Check the Filter Names and make a List of all Filter Pointers.
    VFS_FilterList Filters;
    for( VFS_FilterNameList::const_iterator iter = UsedFilters.begin(); iter != UsedFilters.end(); iter++ )
    {
        // Bad Filter Name?
        if( !VFS_ExistsFilter( *iter ) )
        {
            SetLastError( VFS_ERROR_INVALID_PARAMETER );
            return VFS_FALSE;
        }

        // Add the Filter.
        Filters.push_back( VFS_GetFilter( *iter ) );
    }

    // Check all Files.
    for( VFS_FileNameMap::const_iterator iter2 = Files.begin(); iter2 != Files.end(); iter2++ )
    {
        if( !VFS_File_Exists( ( *iter2 ).first ) )
        {
            SetLastError( VFS_ERROR_NOT_FOUND );
            return VFS_FALSE;
        }

        VFS_String strName;
        VFS_Util_GetName( ( *iter2 ).second, strName );
        if( strName.size() > VFS_MAX_NAME_LENGTH )
        {
            SetLastError( VFS_ERROR_INVALID_PARAMETER );
            return VFS_FALSE;
        }
    }

    // Make a list of the Directories to create.
    typedef vector< VFS_String > NameMap;
    NameMap Dirs;
    for( VFS_FileNameMap::const_iterator iter3 = Files.begin(); iter3 != Files.end(); iter3++ )
    {
        VFS_String strDir;
        VFS_Util_GetPath( ( *iter3 ).second, strDir );
        strDir = ToLower( strDir );
        if( strDir != VFS_TEXT( "" ) && find( Dirs.begin(), Dirs.end(), strDir ) == Dirs.end() )
        {
            // Add the top-level Dirs.
            while( strDir.rfind( VFS_PATH_SEPARATOR ) != VFS_String::npos )
            {
                if( find( Dirs.begin(), Dirs.end(), strDir ) != Dirs.end() )
                    break;
                Dirs.push_back( ToLower( strDir ) );
                if( strDir.size() > VFS_MAX_NAME_LENGTH )
                {
                    SetLastError( VFS_ERROR_INVALID_PARAMETER );
                    return VFS_FALSE;
                }

                strDir = strDir.substr( 0, strDir.rfind( VFS_PATH_SEPARATOR ) );
            }

            if( find( Dirs.begin(), Dirs.end(), strDir ) == Dirs.end() )
            {
                Dirs.push_back( ToLower( strDir ) );
                if( strDir.size() > VFS_MAX_NAME_LENGTH )
                {
                    SetLastError( VFS_ERROR_INVALID_PARAMETER );
                    return VFS_FALSE;
                }
            }
        }
    }

    // (Re)create the Target File.
    VFS_Handle hFile = VFS_File_Create( Info.strPath + VFS_TEXT( "." ) + VFS_ARCHIVE_FILE_EXTENSION, VFS_READ | VFS_WRITE );
    if( hFile == VFS_INVALID_HANDLE_VALUE )
        return VFS_FALSE;

    // Write the Header.
    ARCHIVE_HEADER Header;
    memcpy( Header.ID, ARCHIVE_ID, sizeof( ARCHIVE_ID ) );
    Header.wVersion = VFS_VERSION;
    Header.dwNumFilters = ( VFS_DWORD )Filters.size();
    Header.dwNumDirs = ( VFS_DWORD )Dirs.size();
    Header.dwNumFiles = ( VFS_DWORD )Files.size();
    VFS_DWORD dwWritten;
    if( !VFS_File_Write( hFile, ( const VFS_BYTE* ) &Header, sizeof( ARCHIVE_HEADER ), &dwWritten ) )
    {
        VFS_File_Close( hFile );
        return VFS_FALSE;
    }

    // Write the Filters.
    for( VFS_FilterList::iterator iter4 = Filters.begin(); iter4 != Filters.end(); iter4++ )
    {
        ARCHIVE_FILTER Filter;
        strcpy( Filter.szName, ToLower( ( *iter4 )->GetName() ).c_str() );
        if( !VFS_File_Write( hFile, ( const VFS_BYTE* ) &Filter, sizeof( ARCHIVE_FILTER ) ) )
        {
            VFS_File_Close( hFile );
            return VFS_FALSE;
        }
    }

    // Write the Directories.
    for( NameMap::iterator iter5 = Dirs.begin(); iter5 != Dirs.end(); iter5++ )
    {
        ARCHIVE_DIR Dir;

        // Get the Name of the Dir and add it.
        VFS_String strName;
        VFS_Util_GetName( *iter5, strName );
        strcpy( Dir.szName, ToLower( strName ).c_str() );

        // Remove the <pathsep> and the Name from the path; the rest should be the Parent Directory.
        if( ( *iter5 ).find( VFS_PATH_SEPARATOR ) != VFS_String::npos )
        {
            // Get the Name of the Parent Directory.
            VFS_String strParentDir = ( *iter5 ).substr( 0, ( *iter5 ).rfind( VFS_PATH_SEPARATOR ) );

            // Get the Index of the Parent Directory.
            assert( find( Dirs.begin(), Dirs.end(), ToLower( strParentDir ) ) != Dirs.end() );
            Dir.dwParentIndex = ( VFS_DWORD )( find( Dirs.begin(), Dirs.end(), ToLower( strParentDir ) ) - Dirs.begin() );
        }
        else
            Dir.dwParentIndex = DIR_INDEX_ROOT;

        if( !VFS_File_Write( hFile, ( const VFS_BYTE* ) &Dir, sizeof( ARCHIVE_DIR ) ) )
        {
            VFS_File_Close( hFile );
            return VFS_FALSE;
        }
    }

    // Get the starting offset for the file data.
    VFS_DWORD dwOffset = sizeof( ARCHIVE_HEADER ) + Header.dwNumFilters * sizeof( ARCHIVE_FILTER ) +
                         Header.dwNumDirs * sizeof( ARCHIVE_DIR ) + Header.dwNumFiles * sizeof( ARCHIVE_FILE );

    // Let the Filters store the configuration Data.
    for( VFS_FilterList::iterator iter6 = Filters.begin(); iter6 != Filters.end(); iter6++ )
    {
        // Setup diverse global Variables.
        g_ToBuffer.clear();

        // Call the Saver Proc.
        if( !( *iter6 )->SaveConfigData( Writer ) )
        {
            VFS_File_Close( hFile );
            return VFS_FALSE;
        }

        // Save it.
        VFS_DWORD dwPos = VFS_File_Tell( hFile );
        VFS_File_Seek( hFile, dwOffset, VFS_SET );
        VFS_File_Write( hFile, &*g_ToBuffer.begin(), ( VFS_DWORD )g_ToBuffer.size() );
        VFS_File_Seek( hFile, dwPos, VFS_SET );
        dwOffset += ( VFS_DWORD )g_ToBuffer.size();
    }

    // Write the Files.
    for( VFS_FileNameMap::const_iterator iter7 = Files.begin(); iter7 != Files.end(); iter7++ )
    {
        // Prepare the record.
        ARCHIVE_FILE File;

        // Get the Name of the File and add it.
        VFS_String strName;
        VFS_Util_GetName( ( *iter7 ).second, strName );
        strcpy( File.szName, ToLower( strName ).c_str() );

        // Get the Parent Dir ID.
        if( ( *iter7 ).second.find( VFS_PATH_SEPARATOR ) != VFS_String::npos )
        {
            // Get the Name of the Parent Directory.
            VFS_String strParentDir = ( *iter7 ).second.substr( 0, ( *iter7 ).second.rfind( VFS_PATH_SEPARATOR ) );

            // Get the Index of the Parent Directory.
            assert( find( Dirs.begin(), Dirs.end(), ToLower( strParentDir ) ) != Dirs.end() );
            File.dwDirIndex = ( VFS_DWORD )( find( Dirs.begin(), Dirs.end(), ToLower( strParentDir ) ) - Dirs.begin() );
        }
        else
            File.dwDirIndex = DIR_INDEX_ROOT;

        // Open the Source File.
        VFS_Handle hSrc = VFS_File_Open( ( *iter7 ).first, VFS_READ );
        if( hSrc == VFS_INVALID_HANDLE_VALUE )
        {
            VFS_File_Close( hFile );
            return VFS_FALSE;
        }

        // Store the uncompressed size.
        File.dwUncompressedSize = VFS_File_GetSize( hSrc );

        // Setup diverse global Variables.
        g_FromBuffer.clear();
        g_ToBuffer.clear();

        // Read in the File.
        VFS_DWORD dwRead;
        g_FromPos = 0;
        do
        {
            if( !VFS_File_Read( hSrc, Chunk, FILE_COPY_CHUNK_SIZE, &dwRead ) )
            {
                VFS_File_Close( hSrc );
                VFS_File_Close( hFile );
                return VFS_FALSE;
            }
            g_FromBuffer.reserve( g_FromBuffer.size() + dwRead );
            for( VFS_DWORD dwIndex = 0; dwIndex < dwRead; dwIndex++ )
                g_FromBuffer.push_back( Chunk[ dwIndex ] );
        }
        while( dwRead > 0 );

        // Close the File.
        VFS_File_Close( hSrc );

        // Call the Filters.
        VFS_EntityInfo Info;
        VFS_File_GetInfo( ( *iter7 ).first, Info );
        for( VFS_FilterList::iterator iter8 = Filters.begin(); iter8 != Filters.end(); iter8++ )
        {
            g_FromPos = 0;
            if( !( *iter8 )->Encode( Reader, Writer, Info ) )
            {
                VFS_ErrorCode eError = VFS_GetLastError();
                if( eError == VFS_ERROR_NONE )
                    eError = VFS_ERROR_GENERIC;
                SetLastError( eError );
                VFS_File_Close( hFile );
                return VFS_FALSE;
            }
            g_FromBuffer = g_ToBuffer;
            g_ToBuffer.clear();
        }

        // Store the final Result.
        VFS_DWORD dwPos = VFS_File_Tell( hFile );
        VFS_File_Seek( hFile, dwOffset, VFS_SET );
        VFS_File_Write( hFile, &*g_FromBuffer.begin(), ( VFS_DWORD )g_FromBuffer.size() );
        File.dwCompressedSize = ( VFS_DWORD )g_FromBuffer.size();
        VFS_File_Seek( hFile, dwPos, VFS_SET );
        dwOffset += File.dwCompressedSize;

        if( !VFS_File_Write( hFile, ( const VFS_BYTE* ) &File, sizeof( ARCHIVE_FILE ) ) )
        {
            VFS_File_Close( hFile );
            return VFS_FALSE;
        }
    }

    // Close the File.
    if( !VFS_File_Close( hFile ) )
        return VFS_FALSE;

    return VFS_TRUE;
}
// This define might be needed for VC++ I don't know
// #define STRICT
//! \test Work better if not in the class?
BOOL os_msw::best_terminate_process( HANDLE process_handle, UINT exit_code )
{
    wxLogDebug( "Entering os_msw_best_terminate_process" );
    BOOL successfully_killed         = FALSE;

    // If A 95/98/Me version of Windows...
    //! \test Does this also exclude Me, and include XP and laters?
    if ( wxGetOsVersion() != wxWINDOWS_NT ) {
        //! \test make sure you can pass these handles around OK between functions.
        // ...then just kill it with the crappy ::TerminateProcess()...
        successfully_killed = ::TerminateProcess( process_handle, exit_code );  
        // ... and return success here, and abort the function.
        return successfully_killed;  
    }

    // Otherwise it was a 2000/NT/XP version of windows, and we should use
    // our better way than MSW's ::TerminateProcess().
    DWORD thread_id                 = 0;
    DWORD temp_exit_code            = 0;
    DWORD error_number              = 0;
    HANDLE duplicate_process_handle = INVALID_HANDLE_VALUE;
    HANDLE remote_thread_handle     = NULL;
    HINSTANCE kernel_handle         = GetModuleHandle( "Kernel32" );
    // Try to duplicate a handle, storing whether successful or not.
    BOOL got_a_duplicate_handle_handle = DuplicateHandle( GetCurrentProcess(),
                                                          process_handle,
                                                          GetCurrentProcess(),
                                                          &duplicate_process_handle,
                                                          PROCESS_ALL_ACCESS,
                                                          FALSE,
                                                          0 );
                                                       
    // If it isn't the special case where the process is already dead...
    if ( GetExitCodeProcess( ( got_a_duplicate_handle_handle ) 
         ? duplicate_process_handle : process_handle, &temp_exit_code ) 
         && ( temp_exit_code == STILL_ACTIVE ) ) {
    
       // Get the process address.
       FARPROC process_address;         
       process_address = GetProcAddress( kernel_handle, "ExitProcess" );  
       
       // Create a remote thread using that process address.
       remote_thread_handle = CreateRemoteThread( ( got_a_duplicate_handle_handle ) ? duplicate_process_handle : process_handle,
                                                  NULL,
                                                  0,
                                                  (LPTHREAD_START_ROUTINE)process_address,
                                                  (PVOID)exit_code, 0, &thread_id );
       
       // If couldn't get a handle to the remote thread... 
       if ( remote_thread_handle == NULL ) {
            // ...then set the last error number for the debugger.
            error_number = GetLastError();
       }
       
    // ...otherwise it is already dead.  
    } else {
        error_number = ERROR_PROCESS_ABORTED;
    }
    
    // If we did create manage to a remote thread handle...
    if ( remote_thread_handle ) {
        // ...must wait for a process to terminate to guarantee that it has exited...
        //! \todo INFINITE seems a bit high of a number...
        WaitForSingleObject( ( got_a_duplicate_handle_handle ) ? duplicate_process_handle : process_handle,
                             INFINITE );
        // ...then close handle...
        CloseHandle( remote_thread_handle );
        // ...and report that it was successfully killed.
        successfully_killed = TRUE;
    }
    
    // If we made a duplicate handle...
    if ( got_a_duplicate_handle_handle ) {
        // ...close that handle too.
        CloseHandle( duplicate_process_handle );
    }
    
    // If we couldn't kill, set the last error number for the MSW debugger.
    if ( ! successfully_killed ) {
        SetLastError( error_number );
    }
        
    // Return success or not.    
    return successfully_killed;
}
/******************************************************************************
 *
 * Call the python object with all arguments
 *
 */
static void _CallPythonObject(void *mem,
			      ffi_type *restype,
			      SETFUNC setfunc,
			      PyObject *callable,
			      PyObject *converters,
			      int flags,
			      void **pArgs)
{
	Py_ssize_t i;
	PyObject *result;
	PyObject *arglist = NULL;
	Py_ssize_t nArgs;
	PyObject *error_object = NULL;
	int *space;
#ifdef WITH_THREAD
	PyGILState_STATE state = PyGILState_Ensure();
#endif

	nArgs = PySequence_Length(converters);
	/* Hm. What to return in case of error?
	   For COM, 0xFFFFFFFF seems better than 0.
	*/
	if (nArgs < 0) {
		PrintError("BUG: PySequence_Length");
		goto Done;
	}

	arglist = PyTuple_New(nArgs);
	if (!arglist) {
		PrintError("PyTuple_New()");
		goto Done;
	}
	for (i = 0; i < nArgs; ++i) {
		/* Note: new reference! */
		PyObject *cnv = PySequence_GetItem(converters, i);
		StgDictObject *dict;
		if (cnv)
			dict = PyType_stgdict(cnv);
		else {
			PrintError("Getting argument converter %d\n", i);
			goto Done;
		}

		if (dict && dict->getfunc && !IsSimpleSubType(cnv)) {
			PyObject *v = dict->getfunc(*pArgs, dict->size);
			if (!v) {
				PrintError("create argument %d:\n", i);
				Py_DECREF(cnv);
				goto Done;
			}
			PyTuple_SET_ITEM(arglist, i, v);
			/* XXX XXX XX
			   We have the problem that c_byte or c_short have dict->size of
			   1 resp. 4, but these parameters are pushed as sizeof(int) bytes.
			   BTW, the same problem occurrs when they are pushed as parameters
			*/
		} else if (dict) {
			/* Hm, shouldn't we use CData_AtAddress() or something like that instead? */
			CDataObject *obj = (CDataObject *)PyObject_CallFunctionObjArgs(cnv, NULL);
			if (!obj) {
				PrintError("create argument %d:\n", i);
				Py_DECREF(cnv);
				goto Done;
			}
			if (!CDataObject_Check(obj)) {
				Py_DECREF(obj);
				Py_DECREF(cnv);
				PrintError("unexpected result of create argument %d:\n", i);
				goto Done;
			}
			memcpy(obj->b_ptr, *pArgs, dict->size);
			PyTuple_SET_ITEM(arglist, i, (PyObject *)obj);
#ifdef MS_WIN32
			TryAddRef(dict, obj);
#endif
		} else {
			PyErr_SetString(PyExc_TypeError,
					"cannot build parameter");
			PrintError("Parsing argument %d\n", i);
			Py_DECREF(cnv);
			goto Done;
		}
		Py_DECREF(cnv);
		/* XXX error handling! */
		pArgs++;
	}

#define CHECK(what, x) \
if (x == NULL) _AddTraceback(what, "_ctypes/callbacks.c", __LINE__ - 1), PyErr_Print()

	if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) {
		error_object = get_error_object(&space);
		if (error_object == NULL)
			goto Done;
		if (flags & FUNCFLAG_USE_ERRNO) {
			int temp = space[0];
			space[0] = errno;
			errno = temp;
		}
#ifdef MS_WIN32
		if (flags & FUNCFLAG_USE_LASTERROR) {
			int temp = space[1];
			space[1] = GetLastError();
			SetLastError(temp);
		}
#endif
	}

	result = PyObject_CallObject(callable, arglist);
	CHECK("'calling callback function'", result);

#ifdef MS_WIN32
	if (flags & FUNCFLAG_USE_LASTERROR) {
		int temp = space[1];
		space[1] = GetLastError();
		SetLastError(temp);
	}
#endif
	if (flags & FUNCFLAG_USE_ERRNO) {
		int temp = space[0];
		space[0] = errno;
		errno = temp;
	}
	Py_XDECREF(error_object);

	if ((restype != &ffi_type_void) && result) {
		PyObject *keep;
		assert(setfunc);
#ifdef WORDS_BIGENDIAN
		/* See the corresponding code in callproc.c, around line 961 */
		if (restype->type != FFI_TYPE_FLOAT && restype->size < sizeof(ffi_arg))
			mem = (char *)mem + sizeof(ffi_arg) - restype->size;
#endif
		keep = setfunc(mem, result, 0);
		CHECK("'converting callback result'", keep);
		/* keep is an object we have to keep alive so that the result
		   stays valid.  If there is no such object, the setfunc will
		   have returned Py_None.

		   If there is such an object, we have no choice than to keep
		   it alive forever - but a refcount and/or memory leak will
		   be the result.  EXCEPT when restype is py_object - Python
		   itself knows how to manage the refcount of these objects.
		*/
		if (keep == NULL) /* Could not convert callback result. */
			PyErr_WriteUnraisable(callable);
		else if (keep == Py_None) /* Nothing to keep */
			Py_DECREF(keep);
		else if (setfunc != getentry("O")->setfunc) {
			if (-1 == PyErr_Warn(PyExc_RuntimeWarning,
					     "memory leak in callback function."))
				PyErr_WriteUnraisable(callable);
		}
	}
	Py_XDECREF(result);
  Done:
	Py_XDECREF(arglist);
#ifdef WITH_THREAD
	PyGILState_Release(state);
#endif
}
Exemple #10
0
/*++

ConnectionOpen

    Opens a server connection.

Arguments:
    context - Opaque context passed to <PoolCreate>.

    data    - Pointer to a pointer that receives the DB_CONTEXT structure.

Return Values:
    If the function succeeds, the return value is nonzero (true).

    If the function fails, the return value is zero (false).

--*/
static BOOL FCALL ConnectionOpen(VOID *context, VOID **data)
{
    DB_CONTEXT          *db;
    DB_CONFIG_SERVER    *server;
    DWORD               error;
    DWORD               i;
    INT                 attempt;
    INT                 attemptMax;
    LONG                serverIndex;
    LONG                serverNextIndex;
    MYSQL               *connection;
    my_bool             optReconnect;
    UINT                optTimeout;

    UNREFERENCED_PARAMETER(context);
    ASSERT(data != NULL);
    TRACE("context=%p data=%p", context, data);

    db = MemAllocate(sizeof(DB_CONTEXT));
    if (db == NULL) {
        LOG_ERROR("Unable to allocate memory for database context.");

        error = ERROR_NOT_ENOUGH_MEMORY;
        goto failed;
    }
    ZeroMemory(db, sizeof(DB_CONTEXT));

    //
    // Have the MySQL client library allocate the handle structure for us. This is
    // in case the MYSQL structure changes in a future version of the client library.
    //
    db->handle = mysql_init(NULL);
    if (db->handle == NULL) {
        LOG_ERROR("Unable to allocate memory for MySQL handle.");

        error = ERROR_NOT_ENOUGH_MEMORY;
        goto failed;
    }

    // If the maximum number of attempts were not specified, try all servers
    if (dbConfigGlobal.connAttempts > 0) {
        attemptMax = dbConfigGlobal.connAttempts;
    } else {
        attemptMax = dbConfigServerCount;
    }

    for (attempt = 0; attempt < attemptMax; attempt++) {
        // Use the most recent server for the connection attempt
        serverIndex = dbIndex;
        server      = &dbConfigServers[serverIndex];

        TRACE("Connecting to server #%d [%s] on attempt %lu/%lu.",
            serverIndex, server->name, attempt+1, attemptMax);

        // Set connection options
        optTimeout = (UINT)dbConfigGlobal.connTimeout;
        if (mysql_options(db->handle, MYSQL_OPT_CONNECT_TIMEOUT, &optTimeout) != 0) {
            TRACE("Failed to set connection timeout option.");
        }

        optReconnect = FALSE;
        if (mysql_options(db->handle, MYSQL_OPT_RECONNECT, &optReconnect) != 0) {
            TRACE("Failed to set reconnection option.");
        }

        if (server->compression) {
            if (mysql_options(db->handle, MYSQL_OPT_COMPRESS, 0) != 0) {
                TRACE("Failed to set compression option.");
            }
        }

        if (server->sslEnable) {
            //
            // This function always returns 0. If the SSL setup is incorrect,
            // the call to mysql_real_connect() will return an error.
            //
            mysql_ssl_set(db->handle, server->sslKeyFile, server->sslCertFile,
                server->sslCAFile, server->sslCAPath, server->sslCiphers);
        }

        // Attempt connection with server
        connection = mysql_real_connect(db->handle,
            server->host, server->user, server->password,
            server->database, server->port, NULL, CLIENT_INTERACTIVE);

        if (connection == NULL) {
            LOG_ERROR("Unable to connect to server [%s]: %s",
                server->name, mysql_error(db->handle));

        } else if (mysql_get_server_version(db->handle) < 50019) {
            LOG_ERROR("Unsupported version of MySQL Server [%s]: running v%s, must be v5.0.19 or newer.",
                server->name, mysql_get_server_info(db->handle));

        } else {
            // Pointer values should be the same as from mysql_init()
            ASSERT(connection == db->handle);

            // Allocate pre-compiled statement structures
            for (i = 0; i < ELEMENT_COUNT(db->stmt); i++) {
                db->stmt[i] = mysql_stmt_init(db->handle);
                if (db->stmt[i] == NULL) {
                    LOG_ERROR("Unable to allocate memory for statement structure.");

                    error = ERROR_NOT_ENOUGH_MEMORY;
                    goto failed;
                }
            }

            // Successfully connected, set the global server index
            InterlockedExchange(&dbIndex, serverIndex);

            // Update context's server index and time stamps
            db->index = serverIndex;
            GetSystemTimeAsFileTime(&db->created.fileTime);
            db->used.value = db->created.value;

            LOG_INFO("Connected to %s [%s], running MySQL Server v%s.",
                mysql_get_host_info(db->handle), server->name,
                mysql_get_server_info(db->handle));

            *data = db;
            return TRUE;
        }

        // Unsuccessful connection, continue to the next server
        serverNextIndex = serverIndex + 1;
        if (serverNextIndex >= (LONG)dbConfigServerCount) {
            serverNextIndex = 0;
        }

        //
        // Compare the current server index before swapping values in the
        // event that another thread has already changed the index.
        //
        InterlockedCompareExchange(&dbIndex, serverNextIndex, serverIndex);
    }

    // Unable to connect to any servers
    error = ERROR_CONNECTION_REFUSED;

failed:
    if (db != NULL) {
        ConnectionClose(NULL, db);
    }
    SetLastError(error);
    return FALSE;
}
Exemple #11
0
DWORD ShortPathToLongPath(LPCTSTR lpszShortPath,LPTSTR lpszLongPath,DWORD
                          cchBuffer)
{
    LONG i=0;
    TCHAR path[_MAX_PATH]={0};
    TCHAR ret[_MAX_PATH]={0};
    LONG pos=0, prev_pos=0;
    LONG len=_tcslen(lpszShortPath);

    /* Is the string valid? */
    if (!lpszShortPath) {
        SetLastError(ERROR_INVALID_PARAMETER);
        return 0;
    }

    /* Is the path valid? */
    if (GetFileAttributes(lpszShortPath)==INVALID_FILE_ATTRIBUTES)
        return 0;

    /* Convert "/" to "\" */
    for (i=0;i<len;++i) {
        if (lpszShortPath[i]==_T('/'))
            path[i]=_T('\\');
        else
            path[i]=lpszShortPath[i];
    }

    /* UNC path? */
    if (path[0]==_T('\\') && path[1]==_T('\\')) {
        pos=2;
        for (i=0;i<2;++i) {
            while (path[pos]!=_T('\\') && path[pos]!=_T('\0'))
                ++pos;
            ++pos;
        }
        _tcsncpy(ret,path,pos-1);
    } /* Drive letter? */
    else if (path[1]==_T(':')) {
        if (path[2]==_T('\\'))
            pos=3;
        if (len==3) {
            if (cchBuffer>3)
                _tcscpy(lpszLongPath,lpszShortPath);
            return len;
        }
        _tcsncpy(ret,path,2);
        ret[0] = toupper(ret[0]);
    }

    /* Expand the path for each subpath, and strip trailing backslashes */
    for (prev_pos = pos-1;pos<=len;++pos) {
        if (path[pos]==_T('\\') || (path[pos]==_T('\0') &&
                                    path[pos-1]!=_T('\\'))) {
            WIN32_FIND_DATA fd;
            HANDLE hf=0;
            TCHAR c=path[pos];
            char* new_element;
            path[pos]=_T('\0');

            /* the path[prev_pos+1]... path[pos] range is the part of
               path we're handling right now. We need to find long
               name for that element and add it. */
            new_element = path + prev_pos + 1;

            /* First add separator, but only if there's something in result already. */
            if (ret[0] != _T('\0'))
            {
                _tcscat(ret,_T("\\"));
            }

            /* If it's ".." element, we need to append it, not
               the name in parent that FindFirstFile will return.
               Same goes for "." */

            if (new_element[0] == _T('.') && new_element[1] == _T('\0') ||
                new_element[0] == _T('.') && new_element[1] == _T('.')
                && new_element[2] == _T('\0'))
            {
                _tcscat(ret, new_element);
            }
            else
            {
                hf=FindFirstFile(path, &fd);
                if (hf==INVALID_HANDLE_VALUE)
                    return 0;

                _tcscat(ret,fd.cFileName);
                FindClose(hf);
            }

            path[pos]=c;

            prev_pos = pos;
        }
    }

    len=_tcslen(ret)+1;
    if (cchBuffer>=len)
        _tcscpy(lpszLongPath,ret);

    return len;
}
Exemple #12
0
/*++
Function:
  SetThreadContext

See MSDN doc.
--*/
BOOL
CONTEXT_SetThreadContext(
           DWORD dwProcessId,
           pthread_t self,
           CONST CONTEXT *lpContext)
{
    BOOL ret = FALSE;

#if HAVE_PT_REGS
    struct pt_regs ptrace_registers;
#elif HAVE_BSD_REGS_T
    struct reg ptrace_registers;
#endif

    if (lpContext == NULL)
    {
        ERROR("Invalid lpContext parameter value\n");
        SetLastError(ERROR_NOACCESS);
        goto EXIT;
    }
    
    /* How to consider the case when self is different from the current
       thread of its owner process. Machine registers values could be retreived
       by a ptrace(pid, ...) call or from the "/proc/%pid/reg" file content. 
       Unfortunately, these two methods only depend on process ID, not on 
       thread ID. */
        
    if (dwProcessId == GetCurrentProcessId())
    {
#ifdef FEATURE_PAL_SXS
        // Need to implement SetThreadContext(current thread) for the IX architecture; look at common_signal_handler.
        _ASSERT(FALSE);
#endif // FEATURE_PAL_SXS
        ASSERT("SetThreadContext should be called for cross-process only.\n");
        SetLastError(ERROR_INVALID_PARAMETER);
        goto EXIT;
    }
    
    if (lpContext->ContextFlags  & 
        (CONTEXT_CONTROL | CONTEXT_INTEGER))
    {   
#if HAVE_PT_REGS
        if (ptrace((__ptrace_request)PT_GETREGS, dwProcessId, (caddr_t)&ptrace_registers, 0) == -1)
#elif HAVE_BSD_REGS_T
        if (PAL_PTRACE(PT_GETREGS, dwProcessId, &ptrace_registers, 0) == -1)
#endif
        {
            ASSERT("Failed ptrace(PT_GETREGS, processId:%d) errno:%d (%s)\n",
                   dwProcessId, errno, strerror(errno));
             SetLastError(ERROR_INTERNAL_ERROR);
             goto EXIT;
        }

#if HAVE_PT_REGS
#define ASSIGN_REG(reg) PTREG_##reg(ptrace_registers) = lpContext->reg;
#elif HAVE_BSD_REGS_T
#define ASSIGN_REG(reg) BSDREG_##reg(ptrace_registers) = lpContext->reg;
#else
#define ASSIGN_REG(reg)
	ASSERT("Don't know how to set the context of another process on this platform!");
	return FALSE;
#endif
        if (lpContext->ContextFlags & CONTEXT_CONTROL)
        {
            ASSIGN_CONTROL_REGS
        }
        if (lpContext->ContextFlags & CONTEXT_INTEGER)
        {
            ASSIGN_INTEGER_REGS
        }
#undef ASSIGN_REG

#if HAVE_PT_REGS        
        if (ptrace((__ptrace_request)PT_SETREGS, dwProcessId, (caddr_t)&ptrace_registers, 0) == -1)
#elif HAVE_BSD_REGS_T
        if (PAL_PTRACE(PT_SETREGS, dwProcessId, &ptrace_registers, 0) == -1)
#endif
        {
            ASSERT("Failed ptrace(PT_SETREGS, processId:%d) errno:%d (%s)\n",
                   dwProcessId, errno, strerror(errno));
            SetLastError(ERROR_INTERNAL_ERROR);
            goto EXIT;
        }
    }

    ret = TRUE;
   EXIT:
     return ret;
}
BOOL SFileOpenArchiveEx(
    const char * szMpqName,
    DWORD dwPriority,
    DWORD dwFlags,
    HANDLE * phMPQ,
    DWORD dwAccessMode)
{
    LARGE_INTEGER TempPos;
    TMPQArchive * ha = NULL;            // Archive handle
    HANDLE hFile = INVALID_HANDLE_VALUE;// Opened archive file handle
    DWORD dwMaxBlockIndex = 0;          // Maximum value of block entry
    DWORD dwBlockTableSize = 0;         // Block table size.
    DWORD dwTransferred;                // Number of bytes read
    DWORD dwBytes = 0;                  // Number of bytes to read
    int nError = ERROR_SUCCESS;   

    // Check the right parameters
    if(nError == ERROR_SUCCESS)
    {
        if(szMpqName == NULL || *szMpqName == 0 || phMPQ == NULL)
            nError = ERROR_INVALID_PARAMETER;
    }

    // Ensure that StormBuffer is allocated
    if(nError == ERROR_SUCCESS)
        nError = PrepareStormBuffer();

    // Open the MPQ archive file
    if(nError == ERROR_SUCCESS)
    {
        hFile = CreateFile(szMpqName, dwAccessMode, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
        if(hFile == INVALID_HANDLE_VALUE)
            nError = GetLastError();
    }
    
    // Allocate the MPQhandle
    if(nError == ERROR_SUCCESS)
    {
        if((ha = ALLOCMEM(TMPQArchive, 1)) == NULL)
            nError = ERROR_NOT_ENOUGH_MEMORY;
    }

    // Initialize handle structure and allocate structure for MPQ header
    if(nError == ERROR_SUCCESS)
    {
        memset(ha, 0, sizeof(TMPQArchive));
        strncpy(ha->szFileName, szMpqName, strlen(szMpqName));
        ha->hFile      = hFile;
        ha->dwPriority = dwPriority;
        ha->pHeader    = &ha->Header;
        ha->pListFile  = NULL;
        hFile = INVALID_HANDLE_VALUE;
    }

    // Find the offset of MPQ header within the file
    if(nError == ERROR_SUCCESS)
    {
        LARGE_INTEGER SearchPos = {0};
        LARGE_INTEGER MpqPos = {0};
        DWORD dwHeaderID;

        for(;;)
        {
            // Invalidate the MPQ ID and read the eventual header
            SetFilePointer(ha->hFile, MpqPos.LowPart, &MpqPos.HighPart, FILE_BEGIN);
            ReadFile(ha->hFile, ha->pHeader, sizeof(TMPQHeader2), &dwTransferred, NULL);
            dwHeaderID = BSWAP_INT32_UNSIGNED(ha->pHeader->dwID);

            // Special check : Some MPQs are actually AVI files, only with
            // changed extension.
            if(MpqPos.QuadPart == 0 && IsAviFile(ha->pHeader))
            {
                nError = ERROR_AVI_FILE;
                break;
            }

            // If different number of bytes read, break the loop
            if(dwTransferred != sizeof(TMPQHeader2))
            {
                nError = ERROR_BAD_FORMAT;
                break;
            }

            // If there is the MPQ shunt signature, process it
            if(dwHeaderID == ID_MPQ_SHUNT && ha->pShunt == NULL)
            {
                // Fill the shunt header
                ha->ShuntPos = MpqPos;
                ha->pShunt = &ha->Shunt;
                memcpy(ha->pShunt, ha->pHeader, sizeof(TMPQShunt));
                BSWAP_TMPQSHUNT(ha->pShunt);

                // Set the MPQ pos and repeat the search
                MpqPos.QuadPart = SearchPos.QuadPart + ha->pShunt->dwHeaderPos;
                continue;
            }

            // There must be MPQ header signature
            if(dwHeaderID == ID_MPQ)
            {
                BSWAP_TMPQHEADER(ha->pHeader);

                // Save the position where the MPQ header has been found
                ha->MpqPos = MpqPos;

                // If valid signature has been found, break the loop
                if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_1)
                {
                    // W3M Map Protectors set some garbage value into the "dwHeaderSize"
                    // field of MPQ header. This value is apparently ignored by Storm.dll
                    if(ha->pHeader->dwHeaderSize != sizeof(TMPQHeader) &&
                       ha->pHeader->dwHeaderSize != sizeof(TMPQHeader2))
                    {
                        ha->dwFlags |= MPQ_FLAG_PROTECTED;
                        ha->pHeader->dwHeaderSize = sizeof(TMPQHeader);
                    }

                    if(ha->pHeader->dwHashTablePos < ha->pHeader->dwArchiveSize &&
                       ha->pHeader->dwBlockTablePos < ha->pHeader->dwArchiveSize)
                    {
                        break;
                    }
                }

                if(ha->pHeader->wFormatVersion == MPQ_FORMAT_VERSION_2)
                {
                    break;
                }

                nError = ERROR_NOT_SUPPORTED;
                break;
            }

            // If a MPQ shunt already has been found, 
            // and no MPQ header was at potision pointed by the shunt,
            // then the archive is corrupt
            if(ha->pShunt != NULL)
            {
                nError = ERROR_BAD_FORMAT;
                break;
            }

            // Move to the next possible offset
            SearchPos.QuadPart += 0x200;
            MpqPos = SearchPos;
        }
    }

    // Relocate tables position
    if(nError == ERROR_SUCCESS)
    {
        // Clear the fields not supported in older formats
        if(ha->pHeader->wFormatVersion < MPQ_FORMAT_VERSION_2)
        {
            ha->pHeader->ExtBlockTablePos.QuadPart = 0;
            ha->pHeader->wBlockTablePosHigh = 0;
            ha->pHeader->wHashTablePosHigh = 0;
        }

        ha->dwBlockSize = (0x200 << ha->pHeader->wBlockSize);
        nError = RelocateMpqTablePositions(ha);
    }

    // Allocate buffers
    if(nError == ERROR_SUCCESS)
    {
        //
        // Note that the block table should be as large as the hash table
        // (For later file additions).
        //
        // I have found a MPQ which has the block table larger than
        // the hash table. We should avoid buffer overruns caused by that.
        //
        dwBlockTableSize = max(ha->pHeader->dwHashTableSize, ha->pHeader->dwBlockTableSize);

        ha->pHashTable     = ALLOCMEM(TMPQHash, ha->pHeader->dwHashTableSize);
        ha->pBlockTable    = ALLOCMEM(TMPQBlock, dwBlockTableSize);
        ha->pExtBlockTable = ALLOCMEM(TMPQBlockEx, dwBlockTableSize);
        ha->pbBlockBuffer  = ALLOCMEM(BYTE, ha->dwBlockSize);

        if(!ha->pHashTable || !ha->pBlockTable || !ha->pExtBlockTable || !ha->pbBlockBuffer)
            nError = ERROR_NOT_ENOUGH_MEMORY;
    }

    // Read the hash table into memory
    if(nError == ERROR_SUCCESS)
    {
        dwBytes = ha->pHeader->dwHashTableSize * sizeof(TMPQHash);
        SetFilePointer(ha->hFile, ha->HashTablePos.LowPart, &ha->HashTablePos.HighPart, FILE_BEGIN);
        ReadFile(ha->hFile, ha->pHashTable, dwBytes, &dwTransferred, NULL);

        if(dwTransferred != dwBytes)
            nError = ERROR_FILE_CORRUPT;
    }

    // Decrypt hash table and check if it is correctly decrypted
    if(nError == ERROR_SUCCESS)
    {
        TMPQHash * pHashEnd = ha->pHashTable + ha->pHeader->dwHashTableSize;
        TMPQHash * pHash;

        // We have to convert the hash table from LittleEndian
        BSWAP_ARRAY32_UNSIGNED((DWORD *)ha->pHashTable, (dwBytes / sizeof(DWORD)));
        DecryptHashTable((DWORD *)ha->pHashTable, (BYTE *)"(hash table)", (ha->pHeader->dwHashTableSize * 4));

        // Check hash table if is correctly decrypted
        for(pHash = ha->pHashTable; pHash < pHashEnd; pHash++)
        {
            // Note: Some MPQs from World of Warcraft have wPlatform set to 0x0100.

            // If not free or deleted hash entry, check for valid values
            if(pHash->dwBlockIndex < HASH_ENTRY_DELETED)
            {
                // The block index should not be larger than size of the block table
                if(pHash->dwBlockIndex > ha->pHeader->dwBlockTableSize)
                {
                    nError = ERROR_BAD_FORMAT;
                    break;
                }
            
                // Remember the highest block table entry
                if(pHash->dwBlockIndex > dwMaxBlockIndex)
                    dwMaxBlockIndex = pHash->dwBlockIndex;
            }
        }
    }

    // Now, read the block table
    if(nError == ERROR_SUCCESS)
    {
        memset(ha->pBlockTable, 0, dwBlockTableSize * sizeof(TMPQBlock));

        dwBytes = ha->pHeader->dwBlockTableSize * sizeof(TMPQBlock);
        SetFilePointer(ha->hFile, ha->BlockTablePos.LowPart, &ha->BlockTablePos.HighPart, FILE_BEGIN);
        ReadFile(ha->hFile, ha->pBlockTable, dwBytes, &dwTransferred, NULL);

        // We have to convert every DWORD in ha->block from LittleEndian
        BSWAP_ARRAY32_UNSIGNED((DWORD *)ha->pBlockTable, dwBytes / sizeof(DWORD));

        if(dwTransferred != dwBytes)
            nError = ERROR_FILE_CORRUPT;
    }

    // Decrypt block table.
    // Some MPQs don't have Decrypted block table, e.g. cracked Diablo version
    // We have to check if block table is really encrypted
    if(nError == ERROR_SUCCESS)
    {
        TMPQBlock * pBlockEnd = ha->pBlockTable + ha->pHeader->dwBlockTableSize;
        TMPQBlock * pBlock = ha->pBlockTable;
        BOOL bBlockTableEncrypted = FALSE;

        // Verify all blocks entries in the table
        // The loop usually stops at the first entry
        while(pBlock < pBlockEnd)
        {
            // The lower 8 bits of the MPQ flags are always zero.
            // Note that this may change in next MPQ versions
            if(pBlock->dwFlags & 0x000000FF)
            {
                bBlockTableEncrypted = TRUE;
                break;
            }

            // Move to the next block table entry
            pBlock++;
        }

        if(bBlockTableEncrypted)
        {
            DecryptBlockTable((DWORD *)ha->pBlockTable,
                               (BYTE *)"(block table)",
                                       (ha->pHeader->dwBlockTableSize * 4));
        }
    }

    // Now, read the extended block table.
    // For V1 archives, we still will maintain the extended block table
    // (it will be filled with zeros)
    // TODO: Test with >4GB
    if(nError == ERROR_SUCCESS)
    {
        memset(ha->pExtBlockTable, 0, dwBlockTableSize * sizeof(TMPQBlockEx));

        if(ha->pHeader->ExtBlockTablePos.QuadPart != 0)
        {
            dwBytes = ha->pHeader->dwBlockTableSize * sizeof(TMPQBlockEx);
            SetFilePointer(ha->hFile,
                           ha->ExtBlockTablePos.LowPart,
                          &ha->ExtBlockTablePos.HighPart,
                           FILE_BEGIN);
            ReadFile(ha->hFile, ha->pExtBlockTable, dwBytes, &dwTransferred, NULL);

            // We have to convert every DWORD in ha->block from LittleEndian
            BSWAP_ARRAY16_UNSIGNED((USHORT *)ha->pExtBlockTable, dwBytes / sizeof(USHORT));

            // The extended block table is not encrypted (so far)
            if(dwTransferred != dwBytes)
                nError = ERROR_FILE_CORRUPT;
        }
    }

    // Verify the both block tables (If the MPQ file is not protected)
    if(nError == ERROR_SUCCESS && (ha->dwFlags & MPQ_FLAG_PROTECTED) == 0)
    {
        TMPQBlockEx * pBlockEx = ha->pExtBlockTable;
        TMPQBlock * pBlockEnd = ha->pBlockTable + dwMaxBlockIndex + 1;
        TMPQBlock * pBlock   = ha->pBlockTable;

        // If the MPQ file is not protected,
        // we will check if all sizes in the block table is correct.
        // Note that we will not relocate the block table (change from previous versions)
        for(; pBlock < pBlockEnd; pBlock++, pBlockEx++)
        {
            if(pBlock->dwFlags & MPQ_FILE_EXISTS)
            {
                // Get the 64-bit file position
                TempPos.HighPart = pBlockEx->wFilePosHigh;
                TempPos.LowPart = pBlock->dwFilePos;

                if(TempPos.QuadPart > ha->MpqSize.QuadPart || pBlock->dwCSize > ha->MpqSize.QuadPart)
                {
                    nError = ERROR_BAD_FORMAT;
                    break;
                }
            }
        }
    }

    // If the user didn't specified otherwise, 
    // include the internal listfile to the TMPQArchive structure
    if((dwFlags & MPQ_OPEN_NO_LISTFILE) == 0)
    {
        if(nError == ERROR_SUCCESS)
            SListFileCreateListFile(ha);

        // Add the internal listfile
        if(nError == ERROR_SUCCESS)
            SFileAddListFile((HANDLE)ha, NULL);
    }

    // Cleanup and exit
    if(nError != ERROR_SUCCESS)
    {
        FreeMPQArchive(ha);
        if(hFile != INVALID_HANDLE_VALUE)
            CloseHandle(hFile);
        SetLastError(nError);
    }
    else
    {
        if(pFirstOpen == NULL)
            pFirstOpen = ha;
    }
    *phMPQ = ha;
    return (nError == ERROR_SUCCESS);
}
Exemple #14
0
BOOL AeroAutoSubclass(HWND hWnd, DWORD dwFlags, DWORD dwReserved)
{
    if(!hWnd || !IsWindow(hWnd) || 0L!=dwReserved)  
    {
        SetLastError(ERROR_INVALID_PARAMETER);        
        return FALSE;
    }

    UINT uiRedrawMsg = RegisterWindowMessage(REDRAWSTRING);
    if(!uiRedrawMsg)
        return FALSE; // use the RegisterWindowMessage last error

    CDwmApiImpl *pDwm = NULL;
    CUxThemeAeroImpl *pUxTheme = NULL;
    PAERO_SUBCLASS_WND_DATA pWndData = NULL;
    DWORD dwLastError = ERROR_SUCCESS;
    MARGINS marGlassInset = {-1,-1,-1,-1};
    HRESULT hRes = S_OK;
    bool bBufferedPaintInitialized = false;
    ERROR_PARENT_AERO_SUBCLASS_WND_DATA errParentAeroData;
    ZeroMemory(&errParentAeroData, sizeof(errParentAeroData));
    errParentAeroData.m_dwFlags = dwFlags;
    errParentAeroData.m_hWndParent = hWnd;

    try
    {
        pDwm = new CDwmApiImpl;
    }
    catch (...)
    {
        dwLastError = ERROR_NOT_ENOUGH_MEMORY;
    }

    if(ERROR_SUCCESS!=dwLastError)
        goto CLEANUP;

    try
    {
        pUxTheme = new CUxThemeAeroImpl;
    }
    catch (...)
    {
        dwLastError = ERROR_NOT_ENOUGH_MEMORY;
    }

    if(ERROR_SUCCESS!=dwLastError)
        goto CLEANUP;

    pWndData = (PAERO_SUBCLASS_WND_DATA)LocalAlloc(LPTR, sizeof(AERO_SUBCLASS_WND_DATA));
    if(!pWndData)
    {
        dwLastError = GetLastError();
        goto CLEANUP;
    }

    if(!pDwm->Initialize())
    {
        dwLastError = GetLastError();
        goto CLEANUP;
    }

    if(!pUxTheme->Initialize())
    {
        dwLastError = GetLastError();
        goto CLEANUP;
    }

    if(pDwm->IsDwmCompositionEnabled() && !(dwFlags&ASC_NO_FRAME_EXTENSION))
    {
        /// 
        /// we do not evaluate the return value of pDwm->DwmExtendFrameIntoClientArea, because
        /// if composition is turned off in the tiny little race condition after the previous call
        /// to IsDwmCompositionEnabled and before the following call to DwmExtendFrameIntoClientArea,
        /// we would see DwmExtendFrameIntoClientArea fail. However, if composition is turned on again 
        /// aterwards, the UI can display composition again without problems:
        /// 
        pDwm->DwmExtendFrameIntoClientArea(hWnd, &marGlassInset);
    }

    hRes = pUxTheme->BufferedPaintInit();
    if(FAILED(hRes))
    {
        dwLastError = hRes;
        goto CLEANUP;
    }
    bBufferedPaintInitialized = true;

    if(!SetProp(hWnd, WINDOW_DATA_STRING, pWndData))
    {
        dwLastError = hRes;
        goto CLEANUP;
    }

    errParentAeroData.m_pdwError = &dwLastError;
    errParentAeroData.m_pWndParentAeroData = pWndData;
    pWndData->m_pDwmApiImpl = pDwm;
    pWndData->m_pUxTheme = pUxTheme;
    pWndData->m_uiRedrawMsg = uiRedrawMsg;

    if(dwFlags&ASC_NO_FRAME_EXTENSION)
        pWndData->m_dwFlags |= WD_NO_FRAME_EXTEND;

    if(!EnumChildWindows(hWnd, SubclassChildWindows, (LPARAM)&errParentAeroData))
    {
        if(ERROR_SUCCESS==dwLastError)
            dwLastError = GetLastError();
        goto CLEANUP;
    }
    
    
    if(ERROR_SUCCESS!=dwLastError)
        goto CLEANUP;


    pWndData->m_oldWndProc = (WNDPROC) SetWindowLongPtr(hWnd, GWLP_WNDPROC, (LONG_PTR) WndProc);
    if(!pWndData->m_oldWndProc)
    {
        dwLastError = GetLastError();
        goto CLEANUP;
    }




CLEANUP:

    if(ERROR_SUCCESS!=dwLastError)
    {
        RemoveProp(hWnd, WINDOW_DATA_STRING); // don't care if this fails


        if(pDwm)
            delete pDwm;
        if(pUxTheme)
        {
            if(bBufferedPaintInitialized)
                pUxTheme->BufferedPaintUnInit();
                
            delete pUxTheme;
        }
        if(pWndData)
            VERIFY(!LocalFree(pWndData));

        SetLastError(dwLastError);
        return FALSE;
    }

    return TRUE;
}
Exemple #15
0
HANDLE WrappedOpenGL::wglDXRegisterObjectNV(HANDLE hDevice, void *dxObject, GLuint name,
                                            GLenum type, GLenum access)
{
  RDCASSERT(IsCaptureMode(m_State));

  ID3D11Resource *real = UnwrapDXResource(dxObject);

  if(real == NULL)
  {
    SetLastError(ERROR_OPEN_FAILED);
    return 0;
  }

  WrappedHANDLE *wrapped = new WrappedHANDLE();

  if(type == eGL_RENDERBUFFER)
    wrapped->res = RenderbufferRes(GetCtx(), name);
  else if(type == eGL_NONE)
    wrapped->res = BufferRes(GetCtx(), name);
  else
    wrapped->res = TextureRes(GetCtx(), name);

  GLResourceRecord *record = GetResourceManager()->GetResourceRecord(wrapped->res);

  if(!record)
  {
    RDCERR("Unrecognised object with type %x and name %u", type, name);
    delete wrapped;
    return NULL;
  }

  SERIALISE_TIME_CALL(wrapped->real =
                          m_Real.wglDXRegisterObjectNV(hDevice, real, name, type, access));

  {
    RDCASSERT(record);

    USE_SCRATCH_SERIALISER();
    SCOPED_SERIALISE_CHUNK(gl_CurChunk);
    Serialise_wglDXRegisterObjectNV(ser, wrapped->res, type, dxObject);

    record->AddChunk(scope.Get());
  }

  if(type != eGL_NONE)
  {
    ResourceFormat fmt;
    uint32_t width = 0, height = 0, depth = 0, mips = 0, layers = 0, samples = 0;
    GetDXTextureProperties(dxObject, fmt, width, height, depth, mips, layers, samples);

    // defined as arrays mostly for Coverity code analysis to stay calm about passing
    // them to the *TexParameter* functions
    GLint maxlevel[4] = {GLint(mips - 1), 0, 0, 0};

    m_Real.glTextureParameteriEXT(wrapped->res.name, type, eGL_TEXTURE_MAX_LEVEL, GLint(mips - 1));

    ResourceId texId = record->GetResourceID();
    m_Textures[texId].resource = wrapped->res;
    m_Textures[texId].curType = type;
    m_Textures[texId].width = width;
    m_Textures[texId].height = height;
    m_Textures[texId].depth = RDCMAX(depth, samples);
    m_Textures[texId].samples = samples;
    m_Textures[texId].dimension = 2;
    if(type == eGL_TEXTURE_1D || type == eGL_TEXTURE_1D_ARRAY)
      m_Textures[texId].dimension = 1;
    else if(type == eGL_TEXTURE_3D)
      m_Textures[texId].dimension = 3;

    m_Textures[texId].internalFormat = MakeGLFormat(fmt);
  }

  return wrapped;
}
Exemple #16
0
void SaveHeapLog()
{
    FILE *f;
    _HEAPINFO hi;
    char block[129],*ad;
    block[128]=0;
    int code;
    HANDLE heaps[200];
    DWORD n;
    PROCESS_HEAP_ENTRY phe;

    f=fopen(WriteDir+SLASH+"heap.log","wb");

    SetLastError(0);
    n=GetProcessHeaps(200,heaps);
    heaps[n]=GetProcessHeap();
    n++;
    fprintf(f,"There are %i heaps for Steem\r\n",n);
    for (DWORD i=0; i<n; i++) {
        code=HeapValidate(heaps[i],0,NULL);
        if (code) {
            fprintf(f,"Heap %u okay\r\n",i);
        } else {
            fprintf(f,"Heap %u has an error in it!\r\n",i);
        }
        HeapLock(heaps[i]);
        phe.lpData=NULL;
        while (HeapWalk(heaps[i],&phe)) {
            fprintf(f,"%s%X\r\n","Bad node, address=",(unsigned long)(phe.lpData));
            ad=((char*)phe.lpData)-64;
            for (int n=0; n<128; n++) {
                block[n]=*(ad++);
                if (block[n]==0) block[n]='\\';
                if (block[n]==10) block[n]='\\';
                if (block[n]==13) block[n]='\\';
            }
            fprintf(f,"%s\r\n",block);
        }
        HeapUnlock(heaps[i]);
        if (phe.lpData==NULL) DisplayLastError();
    }

    fprintf(f,"\r\n\r\n");
    code=_heapchk();
    if (code==_HEAPOK) {
        fprintf(f,"%s\r\n","Heap okay, walking:");
    } else if (code==_HEAPBADNODE) {
        fprintf(f,"%s\r\n","Heap has bad node! Walking anyway:");
    }
    hi._pentry=NULL;
    for(;;) {
        code=_rtl_heapwalk(&hi);
        if (code==_HEAPEND) break;
        if (code==_HEAPBADNODE) {
            fprintf(f,"%s%X\r\n","Bad node, address=",(unsigned long)(hi.__pentry));
            ad=((char*)hi._pentry)-64;
            for (int n=0; n<128; n++) {
                block[n]=*(ad++);
                if (block[n]==0) block[n]='\\';
                if (block[n]==10) block[n]='\\';
                if (block[n]==13) block[n]='\\';
            }
            fprintf(f,"%s\r\n",block);
        } else if (code==_HEAPOK) {
            fprintf(f,"%s%X\r\n","Good node, address=",(unsigned long)(hi.__pentry));
        }
    }
    fclose(f);
}
// This does the same as GetVolumePathNamesForVolumeNameW() on Windows XP and
// later. It is built into 32 bit versions of this library to make sure that
// the DLL can load correctly on Windows 2000 as well.
BOOL
WINAPI
ImScsiLegacyGetVolumePathNamesForVolumeName(
__in   LPCWSTR lpszVolumeName,
__out  LPWSTR  lpszVolumePathNames,
__in   DWORD   cchBufferLength,
__out  PDWORD  lpcchReturnLength)
{
    *lpcchReturnLength = 0;

    DWORD dw;
    dw;

    LPWSTR cur_ptr = lpszVolumePathNames;
    LPWSTR end_ptr = lpszVolumePathNames + cchBufferLength;

    WCHAR vol_target[MAX_PATH];

    wcsncpy(vol_target, lpszVolumeName + 4, 44);
    vol_target[44] = 0;

    if (!QueryDosDevice(vol_target, vol_target, _countof(vol_target)))
    {
        return FALSE;
    }

    WHeapMem<WCHAR> dosdevs(UNICODE_STRING_MAX_BYTES,
        HEAP_GENERATE_EXCEPTIONS);

    if (!QueryDosDevice(NULL, dosdevs, (DWORD)dosdevs.Count()))
    {
        return FALSE;
    }

    DWORD good = cchBufferLength >= 2;
    
    *lpcchReturnLength = 2;

    WCHAR dev_target[MAX_PATH];

    SIZE_T length;
    for (LPCWSTR ptr = dosdevs;
        (length = wcslen(ptr)) != 0;
        ptr += length + 1)
    {
        if (good)
        {
            *cur_ptr = 0;
        }

        if ((length != 2) ||
            (ptr[1] != L':') ||
            (!QueryDosDevice(ptr, dev_target, _countof(dev_target))) ||
            (_wcsicmp(dev_target, vol_target) != 0))
        {
            continue;
        }

        *lpcchReturnLength += 4;

        if ((cur_ptr + 4) >= end_ptr)
        {
            good = FALSE;
        }

        if (good)
        {
            swprintf(cur_ptr, L"%ws\\", ptr);
            cur_ptr += 4;
        }
    }

    WCHAR vol_name[50];

    HANDLE volume = FindFirstVolume(vol_name, _countof(vol_name));

    if (volume == INVALID_HANDLE_VALUE)
    {
        return FALSE;
    }

    DWORD error_mode = SetErrorMode(SEM_FAILCRITICALERRORS |
        SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX);

    do
    {
        HANDLE vol_mnt = FindFirstVolumeMountPoint(vol_name, dosdevs,
            (DWORD)dosdevs.Count());

        if (vol_mnt == INVALID_HANDLE_VALUE)
        {
            continue;
        }

        do
        {
            WMem<WCHAR> mnt_path;
            
            mnt_path = ImDiskAllocPrintF(L"%1!ws!%2!ws!", vol_name, dosdevs);

            if (!mnt_path)
            {
                continue;
            }

            WCHAR mnt_vol_name[50];
            if (!GetVolumeNameForVolumeMountPoint(mnt_path, mnt_vol_name,
                _countof(mnt_vol_name)))
            {
                continue;
            }

            if (_wcsicmp(mnt_vol_name, lpszVolumeName) == 0)
            {
                if (ImScsiLegacyGetVolumePathNamesForVolumeName(vol_name,
                    vol_target, _countof(vol_target), &dw))
                {
                    mnt_path = ImDiskAllocPrintF(L"%1!ws!%2!ws!", vol_target,
                        dosdevs);

                }

                size_t len = wcslen(mnt_path) + 1;

                *lpcchReturnLength += (DWORD)len;

                if ((cur_ptr + len) >= end_ptr)
                {
                    good = FALSE;
                }

                if (good)
                {
                    wcscpy(cur_ptr, mnt_path);
                    cur_ptr += len;
                }
            }

        } while (FindNextVolumeMountPoint(vol_mnt, dosdevs,
            (DWORD)dosdevs.Count()));
        
        FindVolumeMountPointClose(vol_mnt);

    } while (FindNextVolume(volume, vol_name, _countof(vol_name)));

    FindVolumeClose(volume);

    SetErrorMode(error_mode);

    if (cur_ptr >= end_ptr)
    {
        good = FALSE;
    }

    if (good)
    {
        *cur_ptr = 0;
        ++*lpcchReturnLength;
    }
    else
    {
        SetLastError(ERROR_MORE_DATA);
    }

    return good;
}
Exemple #18
0
/* load a VxD and return a file handle to it */
HANDLE VXD_Open( LPCWSTR filenameW, DWORD access, SECURITY_ATTRIBUTES *sa )
{
    static const WCHAR dotVxDW[] = {'.','v','x','d',0};
    int i;
    HANDLE handle;
    HMODULE module;
    WCHAR *p, name[16];

    if (!(GetVersion() & 0x80000000))  /* there are no VxDs on NT */
    {
        SetLastError( ERROR_FILE_NOT_FOUND );
        return 0;
    }

    /* normalize the filename */

    if (strlenW( filenameW ) >= sizeof(name)/sizeof(WCHAR) - 4 ||
        strchrW( filenameW, '/' ) || strchrW( filenameW, '\\' ))
    {
        SetLastError( ERROR_FILE_NOT_FOUND );
        return 0;
    }
    strcpyW( name, filenameW );
    strlwrW( name );
    p = strchrW( name, '.' );
    if (!p) strcatW( name, dotVxDW );
    else if (strcmpiW( p, dotVxDW ))  /* existing extension has to be .vxd */
    {
        SetLastError( ERROR_FILE_NOT_FOUND );
        return 0;
    }

    /* try to load the module first */

    if (!(module = LoadLibraryW( name )))
    {
        FIXME( "Unknown/unsupported VxD %s. Try setting Windows version to 'nt40' or 'win31'.\n",
               debugstr_w(name) );
        SetLastError( ERROR_FILE_NOT_FOUND );
        return 0;
    }

    /* register the module in the global list if necessary */

    RtlEnterCriticalSection( &vxd_section );

    for (i = 0; i < MAX_VXD_MODULES; i++)
    {
        if (vxd_modules[i].module == module)
        {
            handle = vxd_modules[i].handle;
            goto done;  /* already registered */
        }
        if (!vxd_modules[i].module)  /* new one, register it */
        {
            struct stat st;
            int fd;

            /* get a file handle to the dummy file */
            if (!(handle = open_vxd_handle( name )))
            {
                FreeLibrary( module );
                goto done;
            }
            wine_server_handle_to_fd( handle, 0, &fd, NULL );
            if (fstat( fd, &st ) != -1)
            {
                vxd_modules[i].dev = st.st_dev;
                vxd_modules[i].ino = st.st_ino;
            }
            vxd_modules[i].module = module;
            vxd_modules[i].handle = handle;
            vxd_modules[i].proc = (DeviceIoProc)GetProcAddress( module, "DeviceIoControl" );
            wine_server_release_fd( handle, fd );
            goto done;
        }
    }

    ERR("too many open VxD modules, please report\n" );
    CloseHandle( handle );
    FreeLibrary( module );
    handle = 0;

done:
    RtlLeaveCriticalSection( &vxd_section );
    if (!DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(), &handle, 0,
                          (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle),
                          DUP_HANDLE_SAME_ACCESS ))
        handle = 0;
    return handle;
}
Exemple #19
0
INT
Test_NtGdiGetRandomRgn(PTESTINFO pti)
{
    HWND hWnd;
    HDC hDC;
    HRGN hrgn, hrgn2;

    /* Create a window */
    hWnd = CreateWindowW(L"BUTTON", L"TestWindow", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
                         CW_USEDEFAULT, CW_USEDEFAULT, 100, 100,
                         NULL, NULL, g_hInstance, 0);
//	UpdateWindow(hWnd);
    hDC = GetDC(hWnd);

    ASSERT(hDC != NULL);

    hrgn = CreateRectRgn(0,0,0,0);
    hrgn2 = CreateRectRgn(3,3,10,10);
    SetLastError(ERROR_SUCCESS);
    RTEST(NtGdiGetRandomRgn(0, hrgn, 0) == -1);
    RTEST(GetLastError() == ERROR_INVALID_HANDLE);

    SetLastError(ERROR_SUCCESS);
    RTEST(NtGdiGetRandomRgn((HDC)2345, hrgn, 1) == -1);
    RTEST(GetLastError() == ERROR_INVALID_HANDLE);

    SetLastError(ERROR_SUCCESS);
    RTEST(NtGdiGetRandomRgn((HDC)2345, hrgn, 10) == -1);
    RTEST(GetLastError() == ERROR_INVALID_HANDLE);

    SetLastError(ERROR_SUCCESS);
    RTEST(NtGdiGetRandomRgn((HDC)2345, (HRGN)10, 10) == -1);
    RTEST(GetLastError() == ERROR_INVALID_HANDLE);

    SetLastError(ERROR_SUCCESS);
    RTEST(NtGdiGetRandomRgn((HDC)2345, 0, 1) == -1);
    RTEST(GetLastError() == ERROR_INVALID_HANDLE);

    SetLastError(ERROR_SUCCESS);
    RTEST(NtGdiGetRandomRgn(hDC, 0, 0) == 0);
    RTEST(NtGdiGetRandomRgn(hDC, 0, 1) == 0);
    RTEST(NtGdiGetRandomRgn(hDC, (HRGN)-5, 0) == 0);
    RTEST(NtGdiGetRandomRgn(hDC, (HRGN)-5, 1) == 0);
    RTEST(NtGdiGetRandomRgn(hDC, hrgn, 0) == 0);
    RTEST(NtGdiGetRandomRgn(hDC, hrgn, 1) == 0);
    TEST(NtGdiGetRandomRgn(hDC, hrgn, 2) == 0);
    RTEST(NtGdiGetRandomRgn(hDC, hrgn, 3) == 0);
    RTEST(NtGdiGetRandomRgn(hDC, hrgn, 4) == 1);
    RTEST(NtGdiGetRandomRgn(hDC, hrgn, 5) == 0);
    RTEST(NtGdiGetRandomRgn(hDC, hrgn, 10) == 0);
    RTEST(NtGdiGetRandomRgn(hDC, hrgn, -10) == 0);
    RTEST(GetLastError() == ERROR_SUCCESS);

    SelectClipRgn(hDC, hrgn2);
    RTEST(NtGdiGetRandomRgn(hDC, 0, 1) == -1);
    RTEST(GetLastError() == ERROR_SUCCESS);
    RTEST(NtGdiGetRandomRgn(hDC, hrgn, 1) == 1);
    RTEST(CombineRgn(hrgn, hrgn, hrgn, RGN_OR) == SIMPLEREGION);
    RTEST(CombineRgn(hrgn, hrgn, hrgn2, RGN_XOR) == NULLREGION);

    SetRectRgn(hrgn2,0,0,0,0);
    SelectClipRgn(hDC, hrgn2);
    RTEST(NtGdiGetRandomRgn(hDC, hrgn, 1) == 1);

    RTEST(CombineRgn(hrgn2, hrgn, hrgn2, RGN_XOR) == NULLREGION);
    RTEST(CombineRgn(hrgn2, hrgn, hrgn, RGN_OR) == NULLREGION);

    SelectClipRgn(hDC, NULL);
    RTEST(NtGdiGetRandomRgn(hDC, hrgn, 1) == 0);


    RTEST(NtGdiGetRandomRgn(hDC, hrgn, 4) == 1);

    RTEST(GetLastError() == ERROR_SUCCESS);

    ReleaseDC(hWnd, hDC);
    DestroyWindow(hWnd);

    return APISTATUS_NORMAL;
}
Exemple #20
0
BOOL EnumImageHijack( AUTORUN_CALLBACK pfnCallback, LPVOID lpParam )
{
	CHKey hKey;
	DWORD dwResult = RegOpenKeyEx( HKEY_LOCAL_MACHINE, 
						"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options",
						0, KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS, (PHKEY)&hKey );
	if(ERROR_SUCCESS != dwResult ) {
		SetLastError( dwResult );
		return FALSE;
	}

	//查询子键数量
	DWORD cSubKey = 0;
	dwResult = RegQueryInfoKey( hKey.GetHandle(), NULL, NULL, 0, &cSubKey, NULL,NULL, NULL, NULL, NULL, NULL, NULL );
	if( ERROR_SUCCESS != dwResult )	{
		SetLastError( dwResult );
		return FALSE;
	}

	LPCTSTR lpszSystemDir = getenv( "SystemRoot" );
	if( lpszSystemDir == NULL ) 
		return FALSE;

	for( DWORD i=0; i < cSubKey; i++ ) {

		AUTORUN_ITEM Item = {0};
		dwResult = RegEnumKey( hKey.GetHandle(), i, Item.Name, sizeof( Item.Name ) );
		if( ERROR_SUCCESS != dwResult ) {
			SetLastError( dwResult );
			continue;
		}
		
		//打开子键
		CHKey hSubKey ;
		dwResult = RegOpenKeyEx( hKey.GetHandle(), Item.Name, 0, KEY_QUERY_VALUE, (PHKEY)&hSubKey );
		if( ERROR_SUCCESS != dwResult ){
			SetLastError( dwResult );
			continue;
		}

		char Buffer[512] = {0};
		DWORD cbSize = sizeof( Buffer );
		dwResult = RegQueryValueEx( hSubKey.GetHandle(), "Debugger", NULL, NULL, (PUCHAR)Buffer, &cbSize );
		if( dwResult != ERROR_SUCCESS ) {
			SetLastError( dwResult );
			continue;
		}

		strncpy( Item.ImagePath, lpszSystemDir, sizeof( Item.ImagePath ) - 1 );
		PathAddBackslash( Item.ImagePath );
		strncat( Item.ImagePath, "System32\\", sizeof( Item.ImagePath ) - strlen( Item.ImagePath ) - 1 );
		strncat( Item.ImagePath, Buffer, sizeof( Item.ImagePath ) - strlen( Item.ImagePath ) - 1 );

		//去掉删除
		PathRemoveArgs( Item.ImagePath );
		PathAddExtension( Item.ImagePath, ".exe" );

		if( !pfnCallback( AUTORUN_IMAGE_HIJACK, &Item, lpParam ) ) {
			SetLastError( ERROR_CANCELLED );
			return FALSE;
		}	
	}

	return TRUE;
}
Exemple #21
0
static void test_other_invalid_parameters(void)
{
    char c_string[] = "Hello World";
    size_t c_string_len = sizeof(c_string);
    WCHAR w_string[] = {'H','e','l','l','o',' ','W','o','r','l','d',0};
    size_t w_string_len = sizeof(w_string) / sizeof(WCHAR);
    BOOL used;
    INT len;

    /* srclen=0 => ERROR_INVALID_PARAMETER */
    SetLastError(0xdeadbeef);
    len = WideCharToMultiByte(CP_ACP, 0, w_string, 0, c_string, c_string_len, NULL, NULL);
    ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());

    SetLastError(0xdeadbeef);
    len = MultiByteToWideChar(CP_ACP, 0, c_string, 0, w_string, w_string_len);
    ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());


    /* dst=NULL but dstlen not 0 => ERROR_INVALID_PARAMETER */
    SetLastError(0xdeadbeef);
    len = WideCharToMultiByte(CP_ACP, 0, w_string, w_string_len, NULL, c_string_len, NULL, NULL);
    ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());

    SetLastError(0xdeadbeef);
    len = MultiByteToWideChar(CP_ACP, 0, c_string, c_string_len, NULL, w_string_len);
    ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());


    /* CP_UTF7, CP_UTF8, or CP_SYMBOL and defchar not NULL => ERROR_INVALID_PARAMETER */
    /* CP_SYMBOL's behavior here is undocumented */
    SetLastError(0xdeadbeef);
    len = WideCharToMultiByte(CP_UTF7, 0, w_string, w_string_len, c_string, c_string_len, c_string, NULL);
    ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());

    SetLastError(0xdeadbeef);
    len = WideCharToMultiByte(CP_UTF8, 0, w_string, w_string_len, c_string, c_string_len, c_string, NULL);
    ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());

    SetLastError(0xdeadbeef);
    len = WideCharToMultiByte(CP_SYMBOL, 0, w_string, w_string_len, c_string, c_string_len, c_string, NULL);
    ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());


    /* CP_UTF7, CP_UTF8, or CP_SYMBOL and used not NULL => ERROR_INVALID_PARAMETER */
    /* CP_SYMBOL's behavior here is undocumented */
    SetLastError(0xdeadbeef);
    len = WideCharToMultiByte(CP_UTF7, 0, w_string, w_string_len, c_string, c_string_len, NULL, &used);
    ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());

    SetLastError(0xdeadbeef);
    len = WideCharToMultiByte(CP_UTF8, 0, w_string, w_string_len, c_string, c_string_len, NULL, &used);
    ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());

    SetLastError(0xdeadbeef);
    len = WideCharToMultiByte(CP_SYMBOL, 0, w_string, w_string_len, c_string, c_string_len, NULL, &used);
    ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());


    /* CP_UTF7, flags not 0 and used not NULL => ERROR_INVALID_PARAMETER */
    /* (tests precedence of ERROR_INVALID_PARAMETER over ERROR_INVALID_FLAGS) */
    /* The same test with CP_SYMBOL instead of CP_UTF7 gives ERROR_INVALID_FLAGS
       instead except on Windows NT4 */
    SetLastError(0xdeadbeef);
    len = WideCharToMultiByte(CP_UTF7, 1, w_string, w_string_len, c_string, c_string_len, NULL, &used);
    ok(len == 0 && GetLastError() == ERROR_INVALID_PARAMETER, "len=%d error=%x\n", len, GetLastError());
}
Exemple #22
0
/***********************************************************************
 *           OleUIInsertObjectW (OLEDLG.20)
 */
UINT WINAPI OleUIInsertObjectW(LPOLEUIINSERTOBJECTW lpOleUIInsertObject)
{
  FIXME("(%p): stub\n", lpOleUIInsertObject);
  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  return OLEUI_FALSE;
}
Exemple #23
0
static void test_utf7_encoding(void)
{
    WCHAR input[16];
    char output[16], expected[16];
    int i, len, expected_len;

    static const BOOL directly_encodable_table[] =
    {
        1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, /* 0x00 - 0x0F */
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x10 - 0x1F */
        1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, /* 0x20 - 0x2F */
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, /* 0x30 - 0x3F */
        0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x40 - 0x4F */
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, /* 0x50 - 0x5F */
        0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, /* 0x60 - 0x6F */
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0  /* 0x70 - 0x7F */
    };
    static const char base64_encoding_table[] =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    const struct
    {
        /* inputs */
        WCHAR src[16];
        int srclen;
        char *dst;
        int dstlen;
        /* expected outputs */
        char expected_dst[16];
        int chars_written;
        int len;
    }
    tests[] =
    {
        /* tests string conversion with srclen=-1 */
        {
            {0x4F60,0x597D,0x5417,0}, -1, output, sizeof(output) - 1,
            "+T2BZfVQX-", 11, 11
        },
        /* tests string conversion with srclen=-2 */
        {
            {0x4F60,0x597D,0x5417,0}, -2, output, sizeof(output) - 1,
            "+T2BZfVQX-", 11, 11
        },
        /* tests string conversion with dstlen=strlen(expected_dst) */
        {
            {0x4F60,0x597D,0x5417,0}, -1, output, 10,
            "+T2BZfVQX-", 10, 0
        },
        /* tests string conversion with dstlen=strlen(expected_dst)+1 */
        {
            {0x4F60,0x597D,0x5417,0}, -1, output, 11,
            "+T2BZfVQX-", 11, 11
        },
        /* tests string conversion with dstlen=strlen(expected_dst)+2 */
        {
            {0x4F60,0x597D,0x5417,0}, -1, output, 12,
            "+T2BZfVQX-", 11, 11
        },
        /* tests dry run with dst=NULL and dstlen=0 */
        {
            {0x4F60,0x597D,0x5417,0}, -1, NULL, 0,
            {0}, 0, 11
        },
        /* tests dry run with dst!=NULL and dstlen=0 */
        {
            {0x4F60,0x597D,0x5417,0}, -1, output, 0,
            {0}, 0, 11
        },
        /* tests srclen < strlenW(src) with directly encodable chars */
        {
            {'h','e','l','l','o',0}, 2, output, sizeof(output) - 1,
            "he", 2, 2
        },
        /* tests srclen < strlenW(src) with non-directly encodable chars */
        {
            {0x4F60,0x597D,0x5417,0}, 2, output, sizeof(output) - 1,
            "+T2BZfQ-", 8, 8
        },
        /* tests a single null char */
        {
            {0}, -1, output, sizeof(output) - 1,
            "", 1, 1
        },
        /* tests a buffer that runs out while not encoding a UTF-7 sequence */
        {
            {'h','e','l','l','o',0}, -1, output, 2,
            "he", 2, 0
        },
        /* tests a buffer that runs out after writing 1 base64 character */
        {
            {0x4F60,0x0001,0}, -1, output, 2,
            "+T", 2, 0
        },
        /* tests a buffer that runs out after writing 2 base64 characters */
        {
            {0x4F60,0x0001,0}, -1, output, 3,
            "+T2", 3, 0
        },
        /* tests a buffer that runs out after writing 3 base64 characters */
        {
            {0x4F60,0x0001,0}, -1, output, 4,
            "+T2A", 4, 0
        },
        /* tests a buffer that runs out just after writing the + sign */
        {
            {0x4F60,0}, -1, output, 1,
            "+", 1, 0
        },
        /* tests a buffer that runs out just before writing the - sign
         * the number of bits to encode here is evenly divisible by 6 */
        {
            {0x4F60,0x597D,0x5417,0}, -1, output, 9,
            "+T2BZfVQX", 9, 0
        },
        /* tests a buffer that runs out just before writing the - sign
         * the number of bits to encode here is NOT evenly divisible by 6 */
        {
            {0x4F60,0}, -1, output, 4,
            "+T2", 3, 0
        },
        /* tests a buffer that runs out in the middle of escaping a + sign */
        {
            {'+',0}, -1, output, 1,
            "+", 1, 0
        }
    };

    /* test which characters are encoded if surrounded by non-encoded characters */
    for (i = 0; i <= 0xFFFF; i++)
    {
        input[0] = ' ';
        input[1] = i;
        input[2] = ' ';
        input[3] = 0;

        memset(output, '#', sizeof(output) - 1);
        output[sizeof(output) - 1] = 0;

        len = WideCharToMultiByte(CP_UTF7, 0, input, 4, output, sizeof(output) - 1, NULL, NULL);

        if (i == '+')
        {
            /* '+' is a special case and is encoded as "+-" */
            expected_len = 5;
            strcpy(expected, " +- ");
        }
        else if (i <= 0x7F && directly_encodable_table[i])
        {
            /* encodes directly */
            expected_len = 4;
            sprintf(expected, " %c ", i);
        }
        else
        {
            /* base64-encodes */
            expected_len = 8;
            sprintf(expected, " +%c%c%c- ",
                    base64_encoding_table[(i & 0xFC00) >> 10],
                    base64_encoding_table[(i & 0x03F0) >> 4],
                    base64_encoding_table[(i & 0x000F) << 2]);
        }

        ok(len == expected_len, "i=0x%04x: expected len=%i, got len=%i\n", i, expected_len, len);
        ok(memcmp(output, expected, expected_len) == 0,
           "i=0x%04x: expected output='%s', got output='%s'\n", i, expected, output);
        ok(output[expected_len] == '#', "i=0x%04x: expected output[%i]='#', got output[%i]=%i\n",
           i, expected_len, expected_len, output[expected_len]);
    }

    /* test which one-byte characters are absorbed into surrounding base64 blocks
     * (Windows always ends the base64 block when it encounters a directly encodable character) */
    for (i = 0; i <= 0xFFFF; i++)
    {
        input[0] = 0x2672;
        input[1] = i;
        input[2] = 0x2672;
        input[3] = 0;

        memset(output, '#', sizeof(output) - 1);
        output[sizeof(output) - 1] = 0;

        len = WideCharToMultiByte(CP_UTF7, 0, input, 4, output, sizeof(output) - 1, NULL, NULL);

        if (i == '+')
        {
            /* '+' is a special case and is encoded as "+-" */
            expected_len = 13;
            strcpy(expected, "+JnI-+-+JnI-");
        }
        else if (i <= 0x7F && directly_encodable_table[i])
        {
            /* encodes directly */
            expected_len = 12;
            sprintf(expected, "+JnI-%c+JnI-", i);
        }
        else
        {
            /* base64-encodes */
            expected_len = 11;
            sprintf(expected, "+Jn%c%c%c%cZy-",
                    base64_encoding_table[8 | ((i & 0xC000) >> 14)],
                    base64_encoding_table[(i & 0x3F00) >> 8],
                    base64_encoding_table[(i & 0x00FC) >> 2],
                    base64_encoding_table[((i & 0x0003) << 4) | 2]);
        }

        ok(len == expected_len, "i=0x%04x: expected len=%i, got len=%i\n", i, expected_len, len);
        ok(memcmp(output, expected, expected_len) == 0,
           "i=0x%04x: expected output='%s', got output='%s'\n", i, expected, output);
        ok(output[expected_len] == '#', "i=0x%04x: expected output[%i]='#', got output[%i]=%i\n",
           i, expected_len, expected_len, output[expected_len]);
    }

    for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
    {
        memset(output, '#', sizeof(output) - 1);
        output[sizeof(output) - 1] = 0;
        SetLastError(0xdeadbeef);

        len = WideCharToMultiByte(CP_UTF7, 0, tests[i].src, tests[i].srclen,
                                  tests[i].dst, tests[i].dstlen, NULL, NULL);

        if (!tests[i].len)
        {
            ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
               "tests[%i]: expected error=0x%x, got error=0x%x\n",
               i, ERROR_INSUFFICIENT_BUFFER, GetLastError());
        }
        ok(len == tests[i].len, "tests[%i]: expected len=%i, got len=%i\n", i, tests[i].len, len);

        if (tests[i].dst)
        {
            ok(memcmp(tests[i].dst, tests[i].expected_dst, tests[i].chars_written) == 0,
               "tests[%i]: expected dst='%s', got dst='%s'\n",
               i, tests[i].expected_dst, tests[i].dst);
            ok(tests[i].dst[tests[i].chars_written] == '#',
               "tests[%i]: expected dst[%i]='#', got dst[%i]=%i\n",
               i, tests[i].chars_written, tests[i].chars_written, tests[i].dst[tests[i].chars_written]);
        }
    }
}
Exemple #24
0
/***********************************************************************
 *           OleUIEditLinksW (OLEDLG.19)
 */
UINT WINAPI OleUIEditLinksW(LPOLEUIEDITLINKSW lpOleUIEditLinks)
{
  FIXME("(%p): stub\n", lpOleUIEditLinks);
  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  return OLEUI_FALSE;
}
Exemple #25
0
static void test_threadcp(void)
{
    static const LCID ENGLISH  = MAKELCID(MAKELANGID(LANG_ENGLISH,  SUBLANG_ENGLISH_US),         SORT_DEFAULT);
    static const LCID HINDI    = MAKELCID(MAKELANGID(LANG_HINDI,    SUBLANG_HINDI_INDIA),        SORT_DEFAULT);
    static const LCID GEORGIAN = MAKELCID(MAKELANGID(LANG_GEORGIAN, SUBLANG_GEORGIAN_GEORGIA),   SORT_DEFAULT);
    static const LCID RUSSIAN  = MAKELCID(MAKELANGID(LANG_RUSSIAN,  SUBLANG_RUSSIAN_RUSSIA),     SORT_DEFAULT);
    static const LCID JAPANESE = MAKELCID(MAKELANGID(LANG_JAPANESE, SUBLANG_JAPANESE_JAPAN),     SORT_DEFAULT);
    static const LCID CHINESE  = MAKELCID(MAKELANGID(LANG_CHINESE,  SUBLANG_CHINESE_SIMPLIFIED), SORT_DEFAULT);

    BOOL islead, islead_acp;
    CPINFOEXA cpi;
    UINT cp, acp;
    int  i, num;
    LCID last;
    BOOL ret;

    struct test {
        LCID lcid;
        UINT threadcp;
    } lcids[] = {
        { HINDI,    0    },
        { GEORGIAN, 0    },
        { ENGLISH,  1252 },
        { RUSSIAN,  1251 },
        { JAPANESE, 932  },
        { CHINESE,  936  }
    };

    struct test_islead_nocp {
        LCID lcid;
        BYTE testchar;
    } isleads_nocp[] = {
        { HINDI,    0x00 },
        { HINDI,    0x81 },
        { HINDI,    0xa0 },
        { HINDI,    0xe0 },

        { GEORGIAN, 0x00 },
        { GEORGIAN, 0x81 },
        { GEORGIAN, 0xa0 },
        { GEORGIAN, 0xe0 },
    };

    struct test_islead {
        LCID lcid;
        BYTE testchar;
        BOOL islead;
    } isleads[] = {
        { ENGLISH,  0x00, FALSE },
        { ENGLISH,  0x81, FALSE },
        { ENGLISH,  0xa0, FALSE },
        { ENGLISH,  0xe0, FALSE },

        { RUSSIAN,  0x00, FALSE },
        { RUSSIAN,  0x81, FALSE },
        { RUSSIAN,  0xa0, FALSE },
        { RUSSIAN,  0xe0, FALSE },

        { JAPANESE, 0x00, FALSE },
        { JAPANESE, 0x81,  TRUE },
        { JAPANESE, 0xa0, FALSE },
        { JAPANESE, 0xe0,  TRUE },

        { CHINESE,  0x00, FALSE },
        { CHINESE,  0x81,  TRUE },
        { CHINESE,  0xa0,  TRUE },
        { CHINESE,  0xe0,  TRUE },
    };

    last = GetThreadLocale();
    acp  = GetACP();

    for (i = 0; i < sizeof(lcids)/sizeof(lcids[0]); i++)
    {
        SetThreadLocale(lcids[i].lcid);

        cp = 0xdeadbeef;
        GetLocaleInfoA(lcids[i].lcid, LOCALE_IDEFAULTANSICODEPAGE|LOCALE_RETURN_NUMBER, (LPSTR)&cp, sizeof(cp));
        ok(cp == lcids[i].threadcp, "wrong codepage %u for lcid %04x, should be %u\n", cp, lcids[i].threadcp, cp);

        /* GetCPInfoEx/GetCPInfo - CP_ACP */
        SetLastError(0xdeadbeef);
        memset(&cpi, 0, sizeof(cpi));
        ret = GetCPInfoExA(CP_ACP, 0, &cpi);
        ok(ret, "GetCPInfoExA failed for lcid %04x, error %d\n", lcids[i].lcid, GetLastError());
        ok(cpi.CodePage == acp, "wrong codepage %u for lcid %04x, should be %u\n", cpi.CodePage, lcids[i].lcid, acp);

        /* WideCharToMultiByte - CP_ACP */
        num = WideCharToMultiByte(CP_ACP, 0, foobarW, -1, NULL, 0, NULL, NULL);
        ok(num == 7, "ret is %d (%04x)\n", num, lcids[i].lcid);

        /* MultiByteToWideChar - CP_ACP */
        num = MultiByteToWideChar(CP_ACP, 0, "foobar", -1, NULL, 0);
        ok(num == 7, "ret is %d (%04x)\n", num, lcids[i].lcid);

        /* GetCPInfoEx/GetCPInfo - CP_THREAD_ACP */
        SetLastError(0xdeadbeef);
        memset(&cpi, 0, sizeof(cpi));
        ret = GetCPInfoExA(CP_THREAD_ACP, 0, &cpi);
        ok(ret, "GetCPInfoExA failed for lcid %04x, error %d\n", lcids[i].lcid, GetLastError());
        if (lcids[i].threadcp)
            ok(cpi.CodePage == lcids[i].threadcp, "wrong codepage %u for lcid %04x, should be %u\n",
               cpi.CodePage, lcids[i].lcid, lcids[i].threadcp);
        else
            ok(cpi.CodePage == acp, "wrong codepage %u for lcid %04x, should be %u\n",
               cpi.CodePage, lcids[i].lcid, acp);

        /* WideCharToMultiByte - CP_THREAD_ACP */
        num = WideCharToMultiByte(CP_THREAD_ACP, 0, foobarW, -1, NULL, 0, NULL, NULL);
        ok(num == 7, "ret is %d (%04x)\n", num, lcids[i].lcid);

        /* MultiByteToWideChar - CP_THREAD_ACP */
        num = MultiByteToWideChar(CP_THREAD_ACP, 0, "foobar", -1, NULL, 0);
        ok(num == 7, "ret is %d (%04x)\n", num, lcids[i].lcid);
    }

    /* IsDBCSLeadByteEx - locales without codepage */
    for (i = 0; i < sizeof(isleads_nocp)/sizeof(isleads_nocp[0]); i++)
    {
        SetThreadLocale(isleads_nocp[i].lcid);

        islead_acp = IsDBCSLeadByteEx(CP_ACP,        isleads_nocp[i].testchar);
        islead     = IsDBCSLeadByteEx(CP_THREAD_ACP, isleads_nocp[i].testchar);

        ok(islead == islead_acp, "wrong islead %i for test char %x in lcid %04x.  should be %i\n",
            islead, isleads_nocp[i].testchar, isleads_nocp[i].lcid, islead_acp);
    }

    /* IsDBCSLeadByteEx - locales with codepage */
    for (i = 0; i < sizeof(isleads)/sizeof(isleads[0]); i++)
    {
        SetThreadLocale(isleads[i].lcid);

        islead = IsDBCSLeadByteEx(CP_THREAD_ACP, isleads[i].testchar);
        ok(islead == isleads[i].islead, "wrong islead %i for test char %x in lcid %04x.  should be %i\n",
            islead, isleads[i].testchar, isleads[i].lcid, isleads[i].islead);
    }

    SetThreadLocale(last);
}
Exemple #26
0
/***********************************************************************
 *           OleUIConvertW (OLEDLG.18)
 */
UINT WINAPI OleUIConvertW(LPOLEUICONVERTW lpOleUIConvert)
{
  FIXME("(%p): stub\n", lpOleUIConvert);
  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  return OLEUI_FALSE;
}
Exemple #27
0
/***********************************************************************
 *		MapAndLoad (IMAGEHLP.@)
 */
BOOL WINAPI MapAndLoad(
  LPSTR pszImageName, LPSTR pszDllPath, PLOADED_IMAGE pLoadedImage,
  BOOL bDotDll, BOOL bReadOnly)
{
  CHAR szFileName[MAX_PATH];
  HANDLE hFile = NULL;
  HANDLE hFileMapping = NULL;
  HMODULE hModule = NULL;
  PIMAGE_NT_HEADERS pNtHeader = NULL;

  TRACE("(%s, %s, %p, %d, %d)\n", pszImageName, pszDllPath, pLoadedImage,
                                    bDotDll, bReadOnly);
  
  /* PathCombine(&szFileName, pszDllPath, pszImageName); */
  /* PathRenameExtension(&szFileName, bDotDll?:"dll":"exe"); */

  /* FIXME: Check if the file already loaded (use IMAGEHLP_pFirstLoadedImage) */
  if(!(hFile = CreateFileA(
    szFileName, GENERIC_READ, 1, /* FIXME: FILE_SHARE_READ not defined */
    NULL, OPEN_EXISTING, 0, NULL)))
    {
      SetLastError(ERROR_FILE_NOT_FOUND);
      goto Error;
    }

  if(!(hFileMapping = CreateFileMappingA(
    hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL)))
    {
      DWORD dwLastError = GetLastError();
      WARN("CreateFileMapping: Error = %ld\n", dwLastError);
      SetLastError(dwLastError);
      goto Error;
    }
  CloseHandle(hFile);
  hFile = NULL;

  if(!(hModule = (HMODULE) MapViewOfFile(
    hFileMapping, FILE_MAP_READ, 0, 0, 0)))
    {
      DWORD dwLastError = GetLastError();
      WARN("MapViewOfFile: Error = %ld\n", dwLastError);
      SetLastError(dwLastError);
      goto Error;
    }

  CloseHandle(hFileMapping);
  hFileMapping=NULL;

  pLoadedImage = HeapAlloc(IMAGEHLP_hHeap, 0, sizeof(LOADED_IMAGE));

  pNtHeader = RtlImageNtHeader(hModule);

  pLoadedImage->ModuleName = HeapAlloc(IMAGEHLP_hHeap, 0, strlen(pszDllPath)+1); /* FIXME: Correct? */
  strcpy( pLoadedImage->ModuleName, pszDllPath );
  pLoadedImage->hFile = hFile;
  pLoadedImage->MappedAddress = (PUCHAR) hModule;
  pLoadedImage->FileHeader = pNtHeader;
  pLoadedImage->Sections = (PIMAGE_SECTION_HEADER)
    ((LPBYTE) &pNtHeader->OptionalHeader +
      pNtHeader->FileHeader.SizeOfOptionalHeader);
  pLoadedImage->NumberOfSections =
    pNtHeader->FileHeader.NumberOfSections;
  pLoadedImage->SizeOfImage =
    pNtHeader->OptionalHeader.SizeOfImage;
  pLoadedImage->Characteristics =
    pNtHeader->FileHeader.Characteristics;
  pLoadedImage->LastRvaSection = pLoadedImage->Sections;

  pLoadedImage->fSystemImage = FALSE; /* FIXME */
  pLoadedImage->fDOSImage = FALSE;    /* FIXME */

  /* FIXME: Make thread safe */
  pLoadedImage->Links.Flink = NULL;
  pLoadedImage->Links.Blink = &IMAGEHLP_pLastLoadedImage->Links;
  if(IMAGEHLP_pLastLoadedImage)
    IMAGEHLP_pLastLoadedImage->Links.Flink = &pLoadedImage->Links;
  IMAGEHLP_pLastLoadedImage = pLoadedImage;
  if(!IMAGEHLP_pFirstLoadedImage)
    IMAGEHLP_pFirstLoadedImage = pLoadedImage;

  return TRUE;

Error:
  if(hModule)
    UnmapViewOfFile((PVOID) hModule);
  if(hFileMapping)
    CloseHandle(hFileMapping);
  if(hFile)
    CloseHandle(hFile);
  return FALSE;
}
Exemple #28
0
/***********************************************************************
 *           OleUIBusyW (OLEDLG.15)
 */
UINT WINAPI OleUIBusyW(LPOLEUIBUSYW lpOleUIBusy)
{
  FIXME("(%p): stub\n", lpOleUIBusy);
  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
  return OLEUI_FALSE;
}
Exemple #29
0
static BOOL fetch_module( DWORD process, DWORD flags, LDR_MODULE** ldr_mod, ULONG* num )
{
    HANDLE                      hProcess;
    PROCESS_BASIC_INFORMATION   pbi;
    PPEB_LDR_DATA               pLdrData;
    NTSTATUS                    status;
    PLIST_ENTRY                 head, curr;
    BOOL                        ret = FALSE;

    *num = 0;

    if (!(flags & TH32CS_SNAPMODULE)) return TRUE;

    if (process)
    {
        hProcess = OpenProcess( PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, process );
        if (!hProcess) return FALSE;
    }
    else
        hProcess = GetCurrentProcess();

    status = NtQueryInformationProcess( hProcess, ProcessBasicInformation,
                                        &pbi, sizeof(pbi), NULL );
    if (!status)
    {
        if (ReadProcessMemory( hProcess, &pbi.PebBaseAddress->LdrData,
                               &pLdrData, sizeof(pLdrData), NULL ) &&
            ReadProcessMemory( hProcess,
                               &pLdrData->InLoadOrderModuleList.Flink,
                               &curr, sizeof(curr), NULL ))
        {
            head = &pLdrData->InLoadOrderModuleList;

            while (curr != head)
            {
                if (!*num)
                    *ldr_mod = HeapAlloc( GetProcessHeap(), 0, sizeof(LDR_MODULE) );
                else
                    *ldr_mod = HeapReAlloc( GetProcessHeap(), 0, *ldr_mod,
                                            (*num + 1) * sizeof(LDR_MODULE) );
                if (!*ldr_mod) break;
                if (!ReadProcessMemory( hProcess,
                                        CONTAINING_RECORD(curr, LDR_MODULE,
                                                          InLoadOrderModuleList),
                                        &(*ldr_mod)[*num],
                                        sizeof(LDR_MODULE), NULL))
                    break;
                curr = (*ldr_mod)[*num].InLoadOrderModuleList.Flink;
                /* if we cannot fetch the strings, then just ignore this LDR_MODULE
                 * and continue loading the other ones in the list
                 */
                if (!fetch_string( hProcess, &(*ldr_mod)[*num].BaseDllName )) continue;
                if (fetch_string( hProcess, &(*ldr_mod)[*num].FullDllName ))
                    (*num)++;
                else
                    HeapFree( GetProcessHeap(), 0, (*ldr_mod)[*num].BaseDllName.Buffer );
            }
            ret = TRUE;
        }
    }
    else SetLastError( RtlNtStatusToDosError( status ) );

    if (process) CloseHandle( hProcess );
    return ret;
}
Exemple #30
0
/*++
Function:
  GetTempPathA

See MSDN.

Notes:
    On Windows, the temp path is determined by the following steps:
    1. The value of the "TMP" environment variable, or if it doesn't exist,
    2. The value of the "TEMP" environment variable, or if it doesn't exist,
    3. The Windows directory.

    On Unix, we follow in spirit:
    1. The value of the "TMPDIR" environment variable, or if it doesn't exist,
    2. The /tmp directory.
    This is the same approach employed by mktemp.

--*/
DWORD
PALAPI
GetTempPathA(
	     IN DWORD nBufferLength,
	     OUT LPSTR lpBuffer)
{
    DWORD dwPathLen = 0;

    PERF_ENTRY(GetTempPathA);
    ENTRY("GetTempPathA(nBufferLength=%u, lpBuffer=%p)\n",
          nBufferLength, lpBuffer);

    if ( !lpBuffer )
    {
        ERROR( "lpBuffer was not a valid pointer.\n" )
        SetLastError( ERROR_INVALID_PARAMETER );
        LOGEXIT("GetTempPathA returns DWORD %u\n", dwPathLen);
        PERF_EXIT(GetTempPathA);
        return 0;
    }

    /* Try the TMPDIR environment variable. This is the same env var checked by mktemp. */
    dwPathLen = GetEnvironmentVariableA("TMPDIR", lpBuffer, nBufferLength);
    if (dwPathLen > 0)
    {
        /* The env var existed. dwPathLen will be the length without null termination 
         * if the entire value was successfully retrieved, or it'll be the length
         * required to store the value with null termination.
         */
        if (dwPathLen < nBufferLength)
        {
            /* The environment variable fit in the buffer. Make sure it ends with '/'. */
            if (lpBuffer[dwPathLen - 1] != '/')
            {
                /* If adding the slash would still fit in our provided buffer, do it.  Otherwise, 
                 * let the caller know how much space would be needed.
                 */
                if (dwPathLen + 2 <= nBufferLength)
                {
                    lpBuffer[dwPathLen++] = '/';
                    lpBuffer[dwPathLen] = '\0';
                }
                else
                {
                    dwPathLen += 2;
                }
            }
        }
        else /* dwPathLen >= nBufferLength */
        {
            /* The value is too long for the supplied buffer.  dwPathLen will now be the
             * length required to hold the value, but we don't know whether that value
             * is going to be '/' terminated.  Since we'll need enough space for the '/', and since
             * a caller would assume that the dwPathLen we return will be sufficient, 
             * we make sure to account for it in dwPathLen even if that means we end up saying
             * one more byte of space is needed than actually is.
             */
            dwPathLen++;
        }
    }
    else /* env var not found or was empty */
    {
        /* no luck, use /tmp/ */
        const char *defaultDir = "/tmp/";
        int defaultDirLen = strlen(defaultDir);
        if (defaultDirLen < nBufferLength)
        {
            dwPathLen = defaultDirLen;
            strcpy_s(lpBuffer, nBufferLength, defaultDir);
        }
        else
        {
            /* get the required length */
            dwPathLen = defaultDirLen + 1;
        }
    }

    if ( dwPathLen >= nBufferLength )
    {
        ERROR("Buffer is too small, need space for %d characters including null termination\n", dwPathLen);
        SetLastError( ERROR_INSUFFICIENT_BUFFER );
    }

    LOGEXIT("GetTempPathA returns DWORD %u\n", dwPathLen);
    PERF_EXIT(GetTempPathA);
    return dwPathLen;
}