diff --git a/dlls/crypt32/sip.c b/dlls/crypt32/sip.c index 3b1e17db0da..ac5e8844e0d 100644 --- a/dlls/crypt32/sip.c +++ b/dlls/crypt32/sip.c @@ -266,12 +266,91 @@ end_function: * Success: TRUE. pgSubject contains the SIP GUID. * Failure: FALSE. (Look at GetLastError()). * + * NOTES + * On failure pgSubject will contain a NULL GUID. + * The handle is always preferred above the filename. */ BOOL WINAPI CryptSIPRetrieveSubjectGuid (LPCWSTR FileName, HANDLE hFileIn, GUID *pgSubject) { - FIXME("(%s %p %p) stub!\n", wine_dbgstr_w(FileName), hFileIn, pgSubject); - return FALSE; + HANDLE hFile; + HANDLE hFilemapped; + LPVOID pMapped; + BOOL bRet = FALSE; + DWORD fileSize; + IMAGE_DOS_HEADER *dos; + /* FIXME, find out if there is a name for this GUID */ + static const GUID unknown = { 0xC689AAB8, 0x8E78, 0x11D0, { 0x8C,0x47,0x00,0xC0,0x4F,0xC2,0x95,0xEE }}; + + TRACE("(%s %p %p)\n", wine_dbgstr_w(FileName), hFileIn, pgSubject); + + if (!pgSubject || (!FileName && !hFileIn)) + { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + /* Set pgSubject to zero's */ + memset(pgSubject, 0 , sizeof(GUID)); + + if (hFileIn) + /* Use the given handle, make sure not to close this one ourselves */ + hFile = hFileIn; + else + { + hFile = CreateFileW(FileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + /* Last error is set by CreateFile */ + if (hFile == INVALID_HANDLE_VALUE) return FALSE; + } + + hFilemapped = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL); + /* Last error is set by CreateFileMapping */ + if (!hFilemapped) goto cleanup3; + + pMapped = MapViewOfFile(hFilemapped, FILE_MAP_READ, 0, 0, 0); + /* Last error is set by MapViewOfFile */ + if (!pMapped) goto cleanup2; + + /* Native checks it right here */ + fileSize = GetFileSize(hFile, NULL); + if (fileSize < 4) + { + SetLastError(ERROR_INVALID_PARAMETER); + goto cleanup1; + } + + /* As everything is in place now we start looking at the file header */ + dos = (IMAGE_DOS_HEADER *)pMapped; + if (dos->e_magic == IMAGE_DOS_SIGNATURE) + { + memcpy(pgSubject, &unknown, sizeof(GUID)); + SetLastError(S_OK); + bRet = TRUE; + goto cleanup1; + } + + /* FIXME + * There is a lot more to be checked: + * - Check for MSFC in the header + * - Check for the keys CryptSIPDllIsMyFileType and CryptSIPDllIsMyFileType2 + * under HKLM\Software\Microsoft\Cryptography\OID\EncodingType 0. Here are + * functions listed that need check if a SIP Provider can deal with the + * given file. + */ + + /* Let's set the most common error for now */ + SetLastError(TRUST_E_SUBJECT_FORM_UNKNOWN); + + /* The 3 different cleanups are here because we shouldn't overwrite the last error */ +cleanup1: + UnmapViewOfFile(pMapped); +cleanup2: + CloseHandle(hFilemapped); +cleanup3: + /* If we didn't open this one we shouldn't close it (hFile is a copy) */ + if (!hFileIn) CloseHandle(hFile); + + return bRet; } /*********************************************************************** diff --git a/dlls/crypt32/tests/sip.c b/dlls/crypt32/tests/sip.c index e213df9e893..61293aa2131 100644 --- a/dlls/crypt32/tests/sip.c +++ b/dlls/crypt32/tests/sip.c @@ -146,9 +146,8 @@ static void test_SIPRetrieveSubjectGUID(void) SetLastError(0xdeadbeef); ret = CryptSIPRetrieveSubjectGuid(NULL, NULL, NULL); ok ( !ret, "Expected CryptSIPRetrieveSubjectGuid to fail\n"); - todo_wine - ok (GetLastError() == ERROR_INVALID_PARAMETER, - "Expected ERROR_INVALID_PARAMETER, got %ld.\n", GetLastError()); + ok (GetLastError() == ERROR_INVALID_PARAMETER, + "Expected ERROR_INVALID_PARAMETER, got %ld.\n", GetLastError()); /* Test with a non-existent file (hopefully) */ SetLastError(0xdeadbeef); @@ -156,13 +155,10 @@ static void test_SIPRetrieveSubjectGUID(void) memset(&subject, 1, sizeof(GUID)); ret = CryptSIPRetrieveSubjectGuid(deadbeef, NULL, &subject); ok ( !ret, "Expected CryptSIPRetrieveSubjectGuid to fail\n"); - todo_wine - { - ok (GetLastError() == ERROR_FILE_NOT_FOUND, - "Expected ERROR_FILE_NOT_FOUND, got %ld.\n", GetLastError()); - ok ( !memcmp(&subject, &nullSubject, sizeof(GUID)), - "Expected a NULL GUID for c:\\deadbeef.dbf, not %s\n", show_guid(&subject)); - } + ok (GetLastError() == ERROR_FILE_NOT_FOUND, + "Expected ERROR_FILE_NOT_FOUND, got %ld.\n", GetLastError()); + ok ( !memcmp(&subject, &nullSubject, sizeof(GUID)), + "Expected a NULL GUID for c:\\deadbeef.dbf, not %s\n", show_guid(&subject)); /* Now with an executable that should exist * @@ -177,28 +173,22 @@ static void test_SIPRetrieveSubjectGUID(void) SetLastError(0xdeadbeef); memset(&subject, 1, sizeof(GUID)); ret = CryptSIPRetrieveSubjectGuid(regeditPathW, NULL, &subject); - todo_wine - { - ok ( ret, "Expected CryptSIPRetrieveSubjectGuid to succeed\n"); - ok ( GetLastError() == ERROR_SUCCESS, - "Expected ERROR_SUCCESS, got 0x%08lx\n", GetLastError()); - ok ( !memcmp(&subject, &unknownGUID, sizeof(GUID)), - "Expected (%s), got (%s).\n", show_guid(&unknownGUID), show_guid(&subject)); - } + ok ( ret, "Expected CryptSIPRetrieveSubjectGuid to succeed\n"); + ok ( GetLastError() == ERROR_SUCCESS, + "Expected ERROR_SUCCESS, got 0x%08lx\n", GetLastError()); + ok ( !memcmp(&subject, &unknownGUID, sizeof(GUID)), + "Expected (%s), got (%s).\n", show_guid(&unknownGUID), show_guid(&subject)); /* The same thing but now with a handle instead of a filename */ file = CreateFileA(regeditPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); SetLastError(0xdeadbeef); memset(&subject, 1, sizeof(GUID)); ret = CryptSIPRetrieveSubjectGuid(NULL, file, &subject); - todo_wine - { - ok ( ret, "Expected CryptSIPRetrieveSubjectGuid to succeed\n"); - ok ( GetLastError() == ERROR_SUCCESS, - "Expected ERROR_SUCCESS, got 0x%08lx\n", GetLastError()); - ok ( !memcmp(&subject, &unknownGUID, sizeof(GUID)), - "Expected (%s), got (%s).\n", show_guid(&unknownGUID), show_guid(&subject)); - } + ok ( ret, "Expected CryptSIPRetrieveSubjectGuid to succeed\n"); + ok ( GetLastError() == ERROR_SUCCESS, + "Expected ERROR_SUCCESS, got 0x%08lx\n", GetLastError()); + ok ( !memcmp(&subject, &unknownGUID, sizeof(GUID)), + "Expected (%s), got (%s).\n", show_guid(&unknownGUID), show_guid(&subject)); CloseHandle(file); /* And both */ @@ -206,14 +196,11 @@ static void test_SIPRetrieveSubjectGUID(void) SetLastError(0xdeadbeef); memset(&subject, 1, sizeof(GUID)); ret = CryptSIPRetrieveSubjectGuid(regeditPathW, file, &subject); - todo_wine - { - ok ( ret, "Expected CryptSIPRetrieveSubjectGuid to succeed\n"); - ok ( GetLastError() == ERROR_SUCCESS, - "Expected ERROR_SUCCESS, got 0x%08lx\n", GetLastError()); - ok ( !memcmp(&subject, &unknownGUID, sizeof(GUID)), - "Expected (%s), got (%s).\n", show_guid(&unknownGUID), show_guid(&subject)); - } + ok ( ret, "Expected CryptSIPRetrieveSubjectGuid to succeed\n"); + ok ( GetLastError() == ERROR_SUCCESS, + "Expected ERROR_SUCCESS, got 0x%08lx\n", GetLastError()); + ok ( !memcmp(&subject, &unknownGUID, sizeof(GUID)), + "Expected (%s), got (%s).\n", show_guid(&unknownGUID), show_guid(&subject)); CloseHandle(file); /* Now with an empty file */ @@ -227,14 +214,11 @@ static void test_SIPRetrieveSubjectGUID(void) memset(&subject, 1, sizeof(GUID)); ret = CryptSIPRetrieveSubjectGuid(tempfileW, NULL, &subject); ok ( !ret, "Expected CryptSIPRetrieveSubjectGuid to fail\n"); - todo_wine - { - ok ( GetLastError() == ERROR_FILE_INVALID || - GetLastError() == S_OK /* Win98 */, - "Expected ERROR_FILE_INVALID or S_OK, got 0x%08lx\n", GetLastError()); - ok ( !memcmp(&subject, &nullSubject, sizeof(GUID)), - "Expected a NULL GUID for empty file %s, not %s\n", tempfile, show_guid(&subject)); - } + ok ( GetLastError() == ERROR_FILE_INVALID || + GetLastError() == S_OK /* Win98 */, + "Expected ERROR_FILE_INVALID or S_OK, got 0x%08lx\n", GetLastError()); + ok ( !memcmp(&subject, &nullSubject, sizeof(GUID)), + "Expected a NULL GUID for empty file %s, not %s\n", tempfile, show_guid(&subject)); /* Use a file with a size of 3 (at least < 4) */ file = CreateFileA(tempfile, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); @@ -245,14 +229,11 @@ static void test_SIPRetrieveSubjectGUID(void) memset(&subject, 1, sizeof(GUID)); ret = CryptSIPRetrieveSubjectGuid(tempfileW, NULL, &subject); ok ( !ret, "Expected CryptSIPRetrieveSubjectGuid to fail\n"); - todo_wine - { - ok ( GetLastError() == ERROR_INVALID_PARAMETER || - GetLastError() == S_OK /* Win98 */, - "Expected ERROR_INVALID_PARAMETER or S_OK, got 0x%08lx\n", GetLastError()); - ok ( !memcmp(&subject, &nullSubject, sizeof(GUID)), - "Expected a NULL GUID for empty file %s, not %s\n", tempfile, show_guid(&subject)); - } + ok ( GetLastError() == ERROR_INVALID_PARAMETER || + GetLastError() == S_OK /* Win98 */, + "Expected ERROR_INVALID_PARAMETER or S_OK, got 0x%08lx\n", GetLastError()); + ok ( !memcmp(&subject, &nullSubject, sizeof(GUID)), + "Expected a NULL GUID for empty file %s, not %s\n", tempfile, show_guid(&subject)); /* And now >= 4 */ file = CreateFileA(tempfile, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); @@ -263,14 +244,11 @@ static void test_SIPRetrieveSubjectGUID(void) memset(&subject, 1, sizeof(GUID)); ret = CryptSIPRetrieveSubjectGuid(tempfileW, NULL, &subject); ok ( !ret, "Expected CryptSIPRetrieveSubjectGuid to fail\n"); - todo_wine - { - ok ( GetLastError() == TRUST_E_SUBJECT_FORM_UNKNOWN || - GetLastError() == S_OK /* Win98 */, - "Expected TRUST_E_SUBJECT_FORM_UNKNOWN or S_OK, got 0x%08lx\n", GetLastError()); - ok ( !memcmp(&subject, &nullSubject, sizeof(GUID)), - "Expected a NULL GUID for empty file %s, not %s\n", tempfile, show_guid(&subject)); - } + ok ( GetLastError() == TRUST_E_SUBJECT_FORM_UNKNOWN || + GetLastError() == S_OK /* Win98 */, + "Expected TRUST_E_SUBJECT_FORM_UNKNOWN or S_OK, got 0x%08lx\n", GetLastError()); + ok ( !memcmp(&subject, &nullSubject, sizeof(GUID)), + "Expected a NULL GUID for empty file %s, not %s\n", tempfile, show_guid(&subject)); /* Clean up */ DeleteFileA(tempfile);