00463 {
00464 struct OIDFunctionSet *set = hFuncSet;
00465 BOOL ret = FALSE;
00466
00467 TRACE("(%p, %d, %s, %08x, %p, %p)\n", hFuncSet, dwEncodingType,
00468 debugstr_w(pwszDll), dwFlags, ppvFuncAddr, phFuncAddr);
00469
00470 if (pwszDll)
00471 {
00472 HMODULE lib;
00473
00474 *phFuncAddr = NULL;
00475 ret = CRYPT_GetFuncFromDll(pwszDll, set->name, &lib, ppvFuncAddr);
00476 if (ret)
00477 {
00478 struct FuncAddr *addr = CryptMemAlloc(sizeof(struct FuncAddr));
00479
00480 if (addr)
00481 {
00482 addr->lib = lib;
00483 addr->dllList = addr->currentDll = NULL;
00484 *phFuncAddr = addr;
00485 }
00486 else
00487 {
00488 FreeLibrary(lib);
00489 *ppvFuncAddr = NULL;
00490 SetLastError(ERROR_OUTOFMEMORY);
00491 ret = FALSE;
00492 }
00493 }
00494 else
00495 SetLastError(ERROR_FILE_NOT_FOUND);
00496 }
00497 else
00498 {
00499 struct FuncAddr *addr = *phFuncAddr;
00500
00501 if (!addr)
00502 {
00503 DWORD size;
00504
00505 ret = CryptGetDefaultOIDDllList(hFuncSet, dwEncodingType, NULL,
00506 &size);
00507 if (ret)
00508 {
00509 LPWSTR dllList = CryptMemAlloc(size * sizeof(WCHAR));
00510
00511 if (dllList)
00512 {
00513 ret = CryptGetDefaultOIDDllList(hFuncSet, dwEncodingType,
00514 dllList, &size);
00515 if (ret)
00516 {
00517 addr = CryptMemAlloc(sizeof(struct FuncAddr));
00518 if (addr)
00519 {
00520 addr->dllList = dllList;
00521 addr->currentDll = dllList;
00522 addr->lib = NULL;
00523 *phFuncAddr = addr;
00524 }
00525 else
00526 {
00527 CryptMemFree(dllList);
00528 SetLastError(ERROR_OUTOFMEMORY);
00529 ret = FALSE;
00530 }
00531 }
00532 }
00533 else
00534 {
00535 SetLastError(ERROR_OUTOFMEMORY);
00536 ret = FALSE;
00537 }
00538 }
00539 }
00540 if (addr)
00541 {
00542 if (!*addr->currentDll)
00543 {
00544 CryptFreeOIDFunctionAddress(*phFuncAddr, 0);
00545 SetLastError(ERROR_FILE_NOT_FOUND);
00546 *phFuncAddr = NULL;
00547 ret = FALSE;
00548 }
00549 else
00550 {
00551
00552
00553
00554
00555 FreeLibrary(addr->lib);
00556 ret = CRYPT_GetFuncFromDll(addr->currentDll, set->name,
00557 &addr->lib, ppvFuncAddr);
00558 if (ret)
00559 {
00560
00561 addr->currentDll += lstrlenW(addr->currentDll) + 1;
00562 *phFuncAddr = addr;
00563 }
00564 else
00565 {
00566 CryptFreeOIDFunctionAddress(*phFuncAddr, 0);
00567 SetLastError(ERROR_FILE_NOT_FOUND);
00568 *phFuncAddr = NULL;
00569 }
00570 }
00571 }
00572 }
00573 return ret;
00574 }