Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1033 lines
25 KiB

  1. /****************************Module*Header******************************\
  2. * Module Name: OBJECT.C
  3. *
  4. * Module Descripton: Object management functions.
  5. *
  6. * Warnings:
  7. *
  8. * Issues:
  9. *
  10. * Public Routines:
  11. *
  12. * Created: 18 March 1996
  13. * Author: Srinivasan Chandrasekar [srinivac]
  14. *
  15. * Copyright (c) 1996, 1997 Microsoft Corporation
  16. \***********************************************************************/
  17. #include "mscms.h"
  18. //
  19. // Number of required and optional functions for CMMs to export
  20. //
  21. #define NUM_REQ_FNS 10
  22. #define NUM_OPT_FNS 6
  23. #define NUM_PS_FNS 3
  24. /******************************************************************************
  25. *
  26. * AllocateHeapObject
  27. *
  28. * Function:
  29. * This functions allocates requested object on the process's heap,
  30. * and returns a handle to it.
  31. *
  32. * Arguments:
  33. * objType - type of object to allocate
  34. *
  35. * Returns:
  36. * Handle to object if successful, NULL otherwise
  37. *
  38. ******************************************************************************/
  39. HANDLE
  40. AllocateHeapObject(
  41. OBJECTTYPE objType
  42. )
  43. {
  44. DWORD dwSize;
  45. POBJHEAD pObject;
  46. switch (objType)
  47. {
  48. case OBJ_PROFILE:
  49. dwSize = sizeof(PROFOBJ);
  50. break;
  51. case OBJ_TRANSFORM:
  52. dwSize = sizeof(TRANSFORMOBJ);
  53. break;
  54. case OBJ_CMM:
  55. dwSize = sizeof(CMMOBJ);
  56. break;
  57. default:
  58. RIP((__TEXT("Allocating invalid object\n")));
  59. dwSize = 0;
  60. break;
  61. }
  62. pObject = (POBJHEAD)MemAlloc(dwSize);
  63. if (!pObject)
  64. {
  65. return NULL;
  66. }
  67. pObject->objType = objType;
  68. return(PTRTOHDL(pObject));
  69. }
  70. /******************************************************************************
  71. *
  72. * FreeHeapObject
  73. *
  74. * Function:
  75. * This functions free an object on the process's heap
  76. *
  77. * Arguments:
  78. * hObject - handle to object to free
  79. *
  80. * Returns:
  81. * No return value
  82. *
  83. ******************************************************************************/
  84. VOID
  85. FreeHeapObject(
  86. HANDLE hObject
  87. )
  88. {
  89. POBJHEAD pObject;
  90. ASSERT(hObject != NULL);
  91. pObject = (POBJHEAD)HDLTOPTR(hObject);
  92. ASSERT(pObject->dwUseCount == 0);
  93. pObject->objType = 0; // in case the handle gets reused
  94. MemFree((PVOID)pObject);
  95. }
  96. /******************************************************************************
  97. *
  98. * ValidHandle
  99. *
  100. * Function:
  101. * This functions checks if a given handle is a valid handle to
  102. * an object of the specified type
  103. *
  104. * Arguments:
  105. * hObject - handle to an object
  106. * objType - type of object to the handle refers to
  107. *
  108. * Returns:
  109. * TRUE is the handle is valid, FALSE otherwise.
  110. *
  111. ******************************************************************************/
  112. BOOL
  113. ValidHandle(
  114. HANDLE hObject,
  115. OBJECTTYPE objType
  116. )
  117. {
  118. POBJHEAD pObject;
  119. BOOL rc;
  120. if (!hObject)
  121. {
  122. return FALSE;
  123. }
  124. pObject = (POBJHEAD)HDLTOPTR(hObject);
  125. rc = !IsBadReadPtr(pObject, sizeof(DWORD)) &&
  126. (pObject->objType == objType);
  127. return rc;
  128. }
  129. /******************************************************************************
  130. *
  131. * ValidProfile
  132. *
  133. * Function:
  134. * This function checks if a given profile is valid by doing some
  135. * sanity checks on it. It is not a fool prof check.
  136. *
  137. * Arguments:
  138. * pProfObj - pointer to profile object
  139. *
  140. * Returns:
  141. * TRUE if it is a valid profile, FALSE otherwise
  142. *
  143. ******************************************************************************/
  144. BOOL ValidProfile(
  145. PPROFOBJ pProfObj
  146. )
  147. {
  148. DWORD dwSize = FIX_ENDIAN(HEADER(pProfObj)->phSize);
  149. return ((dwSize <= pProfObj->dwMapSize) &&
  150. (HEADER(pProfObj)->phSignature == PROFILE_SIGNATURE) &&
  151. (dwSize >= (sizeof(PROFILEHEADER) + sizeof(DWORD))));
  152. }
  153. /******************************************************************************
  154. *
  155. * MemAlloc
  156. *
  157. * Function:
  158. * This functions allocates requested amount of zero initialized memory
  159. * from the process's heap and returns a pointer to it
  160. *
  161. * Arguments:
  162. * dwSize - amount of memory to allocate in bytes
  163. *
  164. * Returns:
  165. * Pointer to memory if successful, NULL otherwise
  166. *
  167. ******************************************************************************/
  168. PVOID
  169. MemAlloc(
  170. DWORD dwSize
  171. )
  172. {
  173. if (dwSize > 0)
  174. return (PVOID)GlobalAllocPtr(GHND | GMEM_ZEROINIT, dwSize);
  175. else
  176. return NULL;
  177. }
  178. /******************************************************************************
  179. *
  180. * MemReAlloc
  181. *
  182. * Function:
  183. * This functions reallocates a block of memory from the process's
  184. * heap and returns a pointer to it
  185. *
  186. * Arguments:
  187. * pMemory - pointer to original memory
  188. * dwNewSize - new size to reallocate
  189. *
  190. * Returns:
  191. * Pointer to memory if successful, NULL otherwise
  192. *
  193. ******************************************************************************/
  194. PVOID
  195. MemReAlloc(
  196. PVOID pMemory,
  197. DWORD dwNewSize
  198. )
  199. {
  200. return (PVOID)GlobalReAllocPtr(pMemory, dwNewSize, GMEM_ZEROINIT);
  201. }
  202. /******************************************************************************
  203. *
  204. * MemFree
  205. *
  206. * Function:
  207. * This functions frees memory from the process's heap
  208. * and returns a handle to it.
  209. *
  210. * Arguments:
  211. * pMemory - pointer to memory to free
  212. *
  213. * Returns:
  214. * No return value
  215. *
  216. ******************************************************************************/
  217. VOID
  218. MemFree(
  219. PVOID pMemory
  220. )
  221. {
  222. DWORD dwErr;
  223. //
  224. // GlobalFree() resets last error, we get and set around it so we don't
  225. // lose anything we have set.
  226. //
  227. dwErr = GetLastError();
  228. GlobalFreePtr(pMemory);
  229. if (dwErr)
  230. {
  231. SetLastError(dwErr);
  232. }
  233. }
  234. /******************************************************************************
  235. *
  236. * MyCopyMemory
  237. *
  238. * Function:
  239. * This functions copies data from one place to another. It takes care
  240. * of overlapping cases. The reason we have our own function and not use
  241. * MoveMemory is that MoveMemory uses memmove which pulls in msvcrt.dll
  242. *
  243. * Arguments:
  244. * pDest - pointer to destination of copy
  245. * pSrc - pointer to source
  246. * dwCount - number of bytes to copy
  247. *
  248. * Returns:
  249. * No return value
  250. *
  251. ******************************************************************************/
  252. VOID
  253. MyCopyMemory(
  254. PBYTE pDest,
  255. PBYTE pSrc,
  256. DWORD dwCount
  257. )
  258. {
  259. //
  260. // Make sure overlapping cases are handled
  261. //
  262. if ((pSrc < pDest) && ((pSrc + dwCount) >= pDest))
  263. {
  264. //
  265. // Overlapping case, copy in reverse
  266. //
  267. pSrc += dwCount - 1;
  268. pDest += dwCount - 1;
  269. while (dwCount--)
  270. {
  271. *pDest-- = *pSrc--;
  272. }
  273. }
  274. else
  275. {
  276. while (dwCount--)
  277. {
  278. *pDest++ = *pSrc++;
  279. }
  280. }
  281. return;
  282. }
  283. /******************************************************************************
  284. *
  285. * ConvertToUnicode
  286. *
  287. * Function:
  288. * This function converts a given Ansi string to Unicode. It optionally
  289. * allocates memory for the Unicode string which the calling program
  290. * needs to free.
  291. *
  292. * Arguments:
  293. * pszAnsiStr - pointer to Ansi string to convert
  294. * ppwszUnicodeStr - pointer to pointer to Unicode string
  295. * bAllocate - If TRUE, allocate memory for Unicode string
  296. *
  297. * Returns:
  298. * TRUE if successful, FALSE otherwise
  299. *
  300. ******************************************************************************/
  301. BOOL
  302. ConvertToUnicode(
  303. PCSTR pszAnsiStr,
  304. PWSTR *ppwszUnicodeStr,
  305. BOOL bAllocate
  306. )
  307. {
  308. DWORD dwLen; // length of Unicode string
  309. dwLen = (lstrlenA(pszAnsiStr) + 1) * sizeof(WCHAR);
  310. //
  311. // Allocate memory for Unicode string
  312. //
  313. if (bAllocate)
  314. {
  315. *ppwszUnicodeStr = (PWSTR)MemAlloc(dwLen);
  316. if (! (*ppwszUnicodeStr))
  317. {
  318. WARNING((__TEXT("Error allocating memory for Unicode name\n")));
  319. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  320. return FALSE;
  321. }
  322. }
  323. //
  324. // Convert Ansi string to Unicode
  325. //
  326. if (! MultiByteToWideChar(CP_ACP, 0, pszAnsiStr, -1,
  327. *ppwszUnicodeStr, dwLen))
  328. {
  329. WARNING((__TEXT("Error converting to Unicode name\n")));
  330. MemFree(*ppwszUnicodeStr);
  331. *ppwszUnicodeStr = NULL;
  332. return FALSE;
  333. }
  334. return TRUE;
  335. }
  336. /******************************************************************************
  337. *
  338. * ConvertToAnsi
  339. *
  340. * Function:
  341. * This function converts a given Unicode string to Ansi. It optionally
  342. * allocates memory for the Ansi string which the calling program needs
  343. * to free.
  344. *
  345. * Arguments:
  346. * pwszUnicodeStr - pointer to Unicode string to convert
  347. * ppszAnsiStr - pointer to pointer to Ansi string.
  348. * bAllocate - If TRUE, allocate memory for Ansi string
  349. *
  350. * Returns:
  351. * TRUE if successful, FALSE otherwise
  352. *
  353. ******************************************************************************/
  354. BOOL
  355. ConvertToAnsi(
  356. PCWSTR pwszUnicodeStr,
  357. PSTR *ppszAnsiStr,
  358. BOOL bAllocate
  359. )
  360. {
  361. DWORD dwLen; // length of Ansi string
  362. BOOL bUsedDefaultChar; // if default characters were used in
  363. // converting Unicode to Ansi
  364. dwLen = (lstrlenW(pwszUnicodeStr) + 1) * sizeof(char);
  365. //
  366. // Allocate memory for Ansi string
  367. //
  368. if (bAllocate)
  369. {
  370. *ppszAnsiStr = (PSTR)MemAlloc(dwLen);
  371. if (! (*ppszAnsiStr))
  372. {
  373. WARNING((__TEXT("Error allocating memory for ANSI name\n")));
  374. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  375. return FALSE;
  376. }
  377. }
  378. //
  379. // Convert Unicode string to Ansi
  380. //
  381. if (! WideCharToMultiByte(CP_ACP, 0, pwszUnicodeStr, -1, *ppszAnsiStr,
  382. dwLen, NULL, &bUsedDefaultChar) || bUsedDefaultChar)
  383. {
  384. WARNING((__TEXT("Error converting to Ansi name\n")));
  385. if (bAllocate)
  386. {
  387. MemFree(*ppszAnsiStr);
  388. *ppszAnsiStr = NULL;
  389. }
  390. return FALSE;
  391. }
  392. return TRUE;
  393. }
  394. /******************************************************************************
  395. *
  396. * ValidColorMatchingModule
  397. *
  398. * Function:
  399. *
  400. * Arguments:
  401. * cmmID - ID identifing the CMM
  402. * pCMMDll - pointer to CMM module path and file name
  403. *
  404. * Returns:
  405. *
  406. ******************************************************************************/
  407. BOOL
  408. ValidColorMatchingModule(
  409. DWORD cmmID,
  410. PTSTR pCMMDll
  411. )
  412. {
  413. HINSTANCE hInstance = NULL;
  414. DWORD (WINAPI *pfnCMGetInfo)(DWORD);
  415. FARPROC pfnCMRequired;
  416. DWORD i;
  417. BOOL rc = FALSE; // Assume failure
  418. //
  419. // Load the CMM
  420. //
  421. hInstance = LoadLibrary(pCMMDll);
  422. if (!hInstance)
  423. {
  424. WARNING((__TEXT("Could not load CMM %s\n"), pCMMDll));
  425. goto EndValidColorMatchingModule;
  426. }
  427. (PVOID) pfnCMGetInfo = (PVOID) GetProcAddress(hInstance, gszCMMReqFns[0]);
  428. if (!pfnCMGetInfo)
  429. {
  430. ERR((__TEXT("CMM does not export CMGetInfo\n")));
  431. goto EndValidColorMatchingModule;
  432. }
  433. //
  434. // Check if the CMM is the right version and reports the same ID
  435. //
  436. if ((pfnCMGetInfo(CMM_VERSION) < 0x00050000) ||
  437. (pfnCMGetInfo(CMM_IDENT) != cmmID))
  438. {
  439. ERR((__TEXT("CMM %s not correct version or reports incorrect ID\n"), pCMMDll));
  440. goto EndValidColorMatchingModule;
  441. }
  442. //
  443. // Check the remaining required functions is presented
  444. //
  445. for (i=1; i<NUM_REQ_FNS; i++)
  446. {
  447. pfnCMRequired = GetProcAddress(hInstance, gszCMMReqFns[i]);
  448. if (!pfnCMRequired)
  449. {
  450. ERR((__TEXT("CMM %s does not export %s\n"), pCMMDll, gszCMMReqFns[i]));
  451. goto EndValidColorMatchingModule;
  452. }
  453. }
  454. rc = TRUE;
  455. EndValidColorMatchingModule:
  456. if (hInstance)
  457. {
  458. FreeLibrary(hInstance);
  459. }
  460. return rc;
  461. }
  462. /******************************************************************************
  463. *
  464. * GetColorMatchingModule
  465. *
  466. * Function:
  467. * This functions returns a pointer to a CMMObject corresponding to
  468. * the ID given. It first looks a the list of CMM objects loaded
  469. * into memory, and if it doesn't find the right one, loads it.
  470. *
  471. * Arguments:
  472. * cmmID - ID identifing the CMM
  473. *
  474. * Returns:
  475. * Pointer to the CMM object if successful, NULL otherwise
  476. *
  477. ******************************************************************************/
  478. PCMMOBJ
  479. GetColorMatchingModule(
  480. DWORD cmmID
  481. )
  482. {
  483. HANDLE hCMMObj;
  484. PCMMOBJ pCMMObj = NULL;
  485. FARPROC *ppTemp;
  486. HINSTANCE hInstance = NULL;
  487. HKEY hkCMM = NULL;
  488. DWORD dwTaskID;
  489. TCHAR szCMMID[5];
  490. DWORD dwType, bufSize, i;
  491. TCHAR szBuffer[MAX_PATH];
  492. BOOL rc = FALSE; // Assume failure
  493. dwTaskID = GetCurrentProcessId();
  494. do {
  495. // Attempt CMM discovery till we find a valid CMM or exhaust the
  496. // valid possibilities.
  497. // First search the already loaded modules for the requested CMM
  498. EnterCriticalSection(&critsec); // Critical section
  499. pCMMObj = gpCMMChain;
  500. while (pCMMObj)
  501. {
  502. if ((pCMMObj->dwCMMID == cmmID) && (pCMMObj->dwTaskID == dwTaskID))
  503. {
  504. pCMMObj->objHdr.dwUseCount++;
  505. break;
  506. }
  507. pCMMObj = pCMMObj->pNext;
  508. }
  509. LeaveCriticalSection(&critsec); // Critical section
  510. if (pCMMObj)
  511. {
  512. // Exit point - we need to clean up anything we allocated
  513. // in this loop.
  514. if (hkCMM)
  515. {
  516. RegCloseKey(hkCMM);
  517. }
  518. // note: we don't cleanup hInstance here because there's no way
  519. // to loop back with a loaded CMM
  520. ASSERT(hInstance==NULL);
  521. return pCMMObj;
  522. }
  523. // The CMM was not already loaded.
  524. // Try load the registry CMM before attempting to load the default
  525. // CMM. This will allow 3rd party vendors to add their own CMMs that
  526. // redefine the system default CMM without having to circumvent SFP.
  527. // To redefine the system default CMM, define 'Win ' in the registry.
  528. // See gszICMatcher for the key to add.
  529. // If we're iterating the discovery process and we've already opened
  530. // the key, avoid leaking by opening it again.
  531. if ((NULL == hkCMM) &&
  532. (ERROR_SUCCESS !=
  533. RegOpenKey(HKEY_LOCAL_MACHINE, gszICMatcher, &hkCMM)))
  534. {
  535. goto OpenDefaultCMM;
  536. }
  537. // Make a string with the CMM ID
  538. #ifdef UNICODE
  539. {
  540. DWORD temp = FIX_ENDIAN(cmmID);
  541. if (!MultiByteToWideChar(CP_ACP, 0, (PSTR)&temp, 4, szCMMID, 5))
  542. {
  543. WARNING((__TEXT("Could not convert cmmID %x to Unicode\n"), temp));
  544. goto OpenDefaultCMM;
  545. }
  546. }
  547. #else
  548. for (i=0; i<4; i++)
  549. {
  550. szCMMID[i] = ((PSTR)&cmmID)[3-i];
  551. }
  552. #endif
  553. szCMMID[4] = '\0';
  554. // Get the file name of the CMM dll if registered.
  555. bufSize = MAX_PATH;
  556. if (ERROR_SUCCESS !=
  557. RegQueryValueEx(
  558. hkCMM, (PTSTR)szCMMID, 0,
  559. &dwType, (BYTE *)szBuffer, &bufSize
  560. ))
  561. {
  562. WARNING((__TEXT("CMM %s not registered\n"), szCMMID));
  563. goto OpenDefaultCMM;
  564. }
  565. // Attempt to load the CMM referenced in the registry.
  566. hInstance = LoadLibrary(szBuffer);
  567. OpenDefaultCMM:
  568. if(!hInstance)
  569. {
  570. // If we failed to load the registry version, or the registry
  571. // entry was not present, try load the default CMM. Note that
  572. // the default CMM could be remapped in the registry.
  573. if(CMM_WINDOWS_DEFAULT != cmmID)
  574. {
  575. // Try again with the default CMM
  576. // It's possible that the default CMM was remapped, so we
  577. // re-attempt the discovery process with the new cmmID.
  578. cmmID = CMM_WINDOWS_DEFAULT;
  579. }
  580. else
  581. {
  582. // We're loading the default cmmID and the it was not remapped
  583. // or we failed to load a remapped default properly using the
  584. // registry name.
  585. // Fall back to the system default CMM.
  586. hInstance = LoadLibrary(gszDefaultCMM);
  587. // There is no fallback for this case. If we can't get the
  588. // system default CMM we must bail.
  589. break;
  590. }
  591. }
  592. } while(!hInstance);
  593. if (!hInstance)
  594. {
  595. // There were no valid possibilities for the CMM.
  596. // Note that we will only hit this case if we failed to load the
  597. // preferred CMM _and_ failed to fall back to the system CMM.
  598. WARNING((__TEXT("Could not load CMM %x\n"), cmmID));
  599. goto EndGetColorMatchingModule;
  600. }
  601. //
  602. // Allocate a CMM object
  603. //
  604. hCMMObj = AllocateHeapObject(OBJ_CMM);
  605. if (!hCMMObj)
  606. {
  607. ERR((__TEXT("Could not allocate CMM object\n")));
  608. goto EndGetColorMatchingModule;
  609. }
  610. pCMMObj = (PCMMOBJ)HDLTOPTR(hCMMObj);
  611. ASSERT(pCMMObj != NULL);
  612. //
  613. // Fill in the CMM object
  614. //
  615. pCMMObj->objHdr.dwUseCount = 1;
  616. pCMMObj->dwCMMID = cmmID;
  617. pCMMObj->dwTaskID = dwTaskID;
  618. pCMMObj->hCMM = hInstance;
  619. ppTemp = (FARPROC *)&pCMMObj->fns.pCMGetInfo;
  620. *ppTemp = GetProcAddress(hInstance, gszCMMReqFns[0]);
  621. ppTemp++;
  622. if (!pCMMObj->fns.pCMGetInfo)
  623. {
  624. ERR((__TEXT("CMM does not export CMGetInfo\n")));
  625. goto EndGetColorMatchingModule;
  626. }
  627. //
  628. // Check if the CMM is the right version and reports the same ID
  629. //
  630. if (pCMMObj->fns.pCMGetInfo(CMM_VERSION) < 0x00050000 ||
  631. pCMMObj->fns.pCMGetInfo(CMM_IDENT) != cmmID)
  632. {
  633. ERR((__TEXT("CMM not correct version or reports incorrect ID\n")));
  634. goto EndGetColorMatchingModule;
  635. }
  636. //
  637. // Load the remaining required functions
  638. //
  639. for (i=1; i<NUM_REQ_FNS; i++)
  640. {
  641. *ppTemp = GetProcAddress(hInstance, gszCMMReqFns[i]);
  642. if (!*ppTemp)
  643. {
  644. ERR((__TEXT("CMM %s does not export %s\n"), szCMMID, gszCMMReqFns[i]));
  645. goto EndGetColorMatchingModule;
  646. }
  647. ppTemp++;
  648. }
  649. //
  650. // Load the optional functions
  651. //
  652. for (i=0; i<NUM_OPT_FNS; i++)
  653. {
  654. *ppTemp = GetProcAddress(hInstance, gszCMMOptFns[i]);
  655. //
  656. // Even these functions are required for Windows default CMM
  657. //
  658. if (cmmID == CMM_WINDOWS_DEFAULT && !*ppTemp)
  659. {
  660. ERR((__TEXT("Windows default CMM does not export %s\n"), gszCMMOptFns[i]));
  661. goto EndGetColorMatchingModule;
  662. }
  663. ppTemp++;
  664. }
  665. //
  666. // Load the PS functions - these are optional even for the default CMM
  667. //
  668. for (i=0; i<NUM_PS_FNS; i++)
  669. {
  670. *ppTemp = GetProcAddress(hInstance, gszPSFns[i]);
  671. ppTemp++;
  672. }
  673. //
  674. // If any of the PS Level2 fns is not exported, do not use this CMM
  675. // for any of the PS Level 2 functionality
  676. //
  677. if (!pCMMObj->fns.pCMGetPS2ColorSpaceArray ||
  678. !pCMMObj->fns.pCMGetPS2ColorRenderingIntent ||
  679. !pCMMObj->fns.pCMGetPS2ColorRenderingDictionary)
  680. {
  681. pCMMObj->fns.pCMGetPS2ColorSpaceArray = NULL;
  682. pCMMObj->fns.pCMGetPS2ColorRenderingIntent = NULL;
  683. pCMMObj->fns.pCMGetPS2ColorRenderingDictionary = NULL;
  684. pCMMObj->dwFlags |= CMM_DONT_USE_PS2_FNS;
  685. }
  686. //
  687. // Add the CMM object to the chain at the beginning
  688. //
  689. EnterCriticalSection(&critsec); // Critical section
  690. pCMMObj->pNext = gpCMMChain;
  691. gpCMMChain = pCMMObj;
  692. LeaveCriticalSection(&critsec); // Critical section
  693. rc = TRUE; // Success!
  694. EndGetColorMatchingModule:
  695. if (!rc)
  696. {
  697. if (pCMMObj)
  698. {
  699. pCMMObj->objHdr.dwUseCount--; // decrement before freeing
  700. FreeHeapObject(hCMMObj);
  701. pCMMObj = NULL;
  702. }
  703. if (hInstance)
  704. {
  705. FreeLibrary(hInstance);
  706. }
  707. }
  708. if (hkCMM)
  709. {
  710. RegCloseKey(hkCMM);
  711. }
  712. return pCMMObj;
  713. }
  714. /******************************************************************************
  715. *
  716. * GetPreferredCMM
  717. *
  718. * Function:
  719. * This functions returns a pointer to the app specified CMM to use
  720. *
  721. * Arguments:
  722. * None
  723. *
  724. * Returns:
  725. * Pointer to app specified CMM object on success, NULL otherwise
  726. *
  727. ******************************************************************************/
  728. PCMMOBJ GetPreferredCMM(
  729. )
  730. {
  731. PCMMOBJ pCMMObj;
  732. EnterCriticalSection(&critsec); // Critical section
  733. pCMMObj = gpPreferredCMM;
  734. if (pCMMObj)
  735. {
  736. //
  737. // Increment use count
  738. //
  739. pCMMObj->objHdr.dwUseCount++;
  740. }
  741. LeaveCriticalSection(&critsec); // Critical section
  742. return pCMMObj;
  743. }
  744. /******************************************************************************
  745. *
  746. * ReleaseColorMatchingModule
  747. *
  748. * Function:
  749. * This functions releases a CMM object. If the ref count goes to
  750. * zero, it unloads the CMM and frees all memory associated with it.
  751. *
  752. * Arguments:
  753. * pCMMObj - pointer to CMM object to release
  754. *
  755. * Returns:
  756. * No return value
  757. *
  758. ******************************************************************************/
  759. VOID
  760. ReleaseColorMatchingModule(
  761. PCMMOBJ pCMMObj
  762. )
  763. {
  764. EnterCriticalSection(&critsec); // Critical section
  765. ASSERT(pCMMObj->objHdr.dwUseCount > 0);
  766. pCMMObj->objHdr.dwUseCount--;
  767. if (pCMMObj->objHdr.dwUseCount == 0)
  768. {
  769. //
  770. // Unloading the CMM everytime a transform is freed might not be
  771. // very efficient. So for now, I am not going to unload it. When
  772. // the app terminates, kernel should unload all dll's loaded by
  773. // this app
  774. //
  775. }
  776. LeaveCriticalSection(&critsec); // Critical section
  777. return;
  778. }
  779. #if DBG
  780. /******************************************************************************
  781. *
  782. * MyDebugPrint
  783. *
  784. * Function:
  785. * This function takes a format string and paramters, composes a string
  786. * and sends it out to the debug port. Available only in debug build.
  787. *
  788. * Arguments:
  789. * pFormat - pointer to format string
  790. * ....... - parameters based on the format string like printf()
  791. *
  792. * Returns:
  793. * No return value
  794. *
  795. ******************************************************************************/
  796. VOID
  797. MyDebugPrintA(
  798. PSTR pFormat,
  799. ...
  800. )
  801. {
  802. char szBuffer[256];
  803. va_list arglist;
  804. va_start(arglist, pFormat);
  805. wvsprintfA(szBuffer, pFormat, arglist);
  806. va_end(arglist);
  807. OutputDebugStringA(szBuffer);
  808. return;
  809. }
  810. VOID
  811. MyDebugPrintW(
  812. PWSTR pFormat,
  813. ...
  814. )
  815. {
  816. WCHAR szBuffer[256];
  817. va_list arglist;
  818. va_start(arglist, pFormat);
  819. wvsprintfW(szBuffer, pFormat, arglist);
  820. va_end(arglist);
  821. OutputDebugStringW(szBuffer);
  822. return;
  823. }
  824. /******************************************************************************
  825. *
  826. * StripDirPrefixA
  827. *
  828. * Function:
  829. * This function takes a path name and returns a pointer to the filename
  830. * part. This is availabel only for the debug build.
  831. *
  832. * Arguments:
  833. * pszPathName - path name of file (can be file name alone)
  834. *
  835. * Returns:
  836. * A pointer to the file name
  837. *
  838. ******************************************************************************/
  839. PSTR
  840. StripDirPrefixA(
  841. PSTR pszPathName
  842. )
  843. {
  844. DWORD dwLen = lstrlenA(pszPathName);
  845. pszPathName += dwLen - 1; // go to the end
  846. while (*pszPathName != '\\' && dwLen--)
  847. {
  848. pszPathName--;
  849. }
  850. return pszPathName + 1;
  851. }
  852. #endif