Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

object.c

Go to the documentation of this file.
00001 /****************************Module*Header******************************\ 00002 * Module Name: OBJECT.C 00003 * 00004 * Module Descripton: Object management functions. 00005 * 00006 * Warnings: 00007 * 00008 * Issues: 00009 * 00010 * Public Routines: 00011 * 00012 * Created: 18 March 1996 00013 * Author: Srinivasan Chandrasekar [srinivac] 00014 * 00015 * Copyright (c) 1996, 1997 Microsoft Corporation 00016 \***********************************************************************/ 00017 00018 #include "mscms.h" 00019 00020 // 00021 // Number of required and optional functions for CMMs to export 00022 // 00023 00024 #define NUM_REQ_FNS 10 00025 #define NUM_OPT_FNS 6 00026 #define NUM_PS_FNS 3 00027 00028 00029 /****************************************************************************** 00030 * 00031 * AllocateHeapObject 00032 * 00033 * Function: 00034 * This functions allocates requested object on the process's heap, 00035 * and returns a handle to it. 00036 * 00037 * Arguments: 00038 * objType - type of object to allocate 00039 * 00040 * Returns: 00041 * Handle to object if successful, NULL otherwise 00042 * 00043 ******************************************************************************/ 00044 00045 HANDLE 00046 AllocateHeapObject( 00047 OBJECTTYPE objType 00048 ) 00049 { 00050 DWORD dwSize; 00051 POBJHEAD pObject; 00052 00053 switch (objType) 00054 { 00055 case OBJ_PROFILE: 00056 dwSize = sizeof(PROFOBJ); 00057 break; 00058 00059 case OBJ_TRANSFORM: 00060 dwSize = sizeof(TRANSFORMOBJ); 00061 break; 00062 00063 case OBJ_CMM: 00064 dwSize = sizeof(CMMOBJ); 00065 break; 00066 00067 default: 00068 RIP((__TEXT("Allocating invalid object\n"))); 00069 dwSize = 0; 00070 break; 00071 } 00072 00073 pObject = (POBJHEAD)MemAlloc(dwSize); 00074 00075 if (!pObject) 00076 { 00077 return NULL; 00078 } 00079 00080 pObject->objType = objType; 00081 00082 return(PTRTOHDL(pObject)); 00083 } 00084 00085 00086 /****************************************************************************** 00087 * 00088 * FreeHeapObject 00089 * 00090 * Function: 00091 * This functions free an object on the process's heap 00092 * 00093 * Arguments: 00094 * hObject - handle to object to free 00095 * 00096 * Returns: 00097 * No return value 00098 * 00099 ******************************************************************************/ 00100 00101 VOID 00102 FreeHeapObject( 00103 HANDLE hObject 00104 ) 00105 { 00106 POBJHEAD pObject; 00107 00108 ASSERT(hObject != NULL); 00109 00110 pObject = (POBJHEAD)HDLTOPTR(hObject); 00111 00112 ASSERT(pObject->dwUseCount == 0); 00113 00114 pObject->objType = 0; // in case the handle gets reused 00115 00116 MemFree((PVOID)pObject); 00117 } 00118 00119 00120 /****************************************************************************** 00121 * 00122 * ValidHandle 00123 * 00124 * Function: 00125 * This functions checks if a given handle is a valid handle to 00126 * an object of the specified type 00127 * 00128 * Arguments: 00129 * hObject - handle to an object 00130 * objType - type of object to the handle refers to 00131 * 00132 * Returns: 00133 * TRUE is the handle is valid, FALSE otherwise. 00134 * 00135 ******************************************************************************/ 00136 00137 BOOL 00138 ValidHandle( 00139 HANDLE hObject, 00140 OBJECTTYPE objType 00141 ) 00142 { 00143 POBJHEAD pObject; 00144 BOOL rc; 00145 00146 if (!hObject) 00147 { 00148 return FALSE; 00149 } 00150 00151 pObject = (POBJHEAD)HDLTOPTR(hObject); 00152 00153 rc = !IsBadReadPtr(pObject, sizeof(DWORD)) && 00154 (pObject->objType == objType); 00155 00156 return rc; 00157 } 00158 00159 00160 /****************************************************************************** 00161 * 00162 * ValidProfile 00163 * 00164 * Function: 00165 * This function checks if a given profile is valid by doing some 00166 * sanity checks on it. It is not a fool prof check. 00167 * 00168 * Arguments: 00169 * pProfObj - pointer to profile object 00170 * 00171 * Returns: 00172 * TRUE if it is a valid profile, FALSE otherwise 00173 * 00174 ******************************************************************************/ 00175 00176 BOOL ValidProfile( 00177 PPROFOBJ pProfObj 00178 ) 00179 { 00180 DWORD dwSize = FIX_ENDIAN(HEADER(pProfObj)->phSize); 00181 00182 return ((dwSize <= pProfObj->dwMapSize) && 00183 (HEADER(pProfObj)->phSignature == PROFILE_SIGNATURE) && 00184 (dwSize >= (sizeof(PROFILEHEADER) + sizeof(DWORD)))); 00185 } 00186 00187 00188 /****************************************************************************** 00189 * 00190 * MemAlloc 00191 * 00192 * Function: 00193 * This functions allocates requested amount of zero initialized memory 00194 * from the process's heap and returns a pointer to it 00195 * 00196 * Arguments: 00197 * dwSize - amount of memory to allocate in bytes 00198 * 00199 * Returns: 00200 * Pointer to memory if successful, NULL otherwise 00201 * 00202 ******************************************************************************/ 00203 00204 PVOID 00205 MemAlloc( 00206 DWORD dwSize 00207 ) 00208 { 00209 if (dwSize > 0) 00210 return (PVOID)GlobalAllocPtr(GHND | GMEM_ZEROINIT, dwSize); 00211 else 00212 return NULL; 00213 } 00214 00215 00216 /****************************************************************************** 00217 * 00218 * MemReAlloc 00219 * 00220 * Function: 00221 * This functions reallocates a block of memory from the process's 00222 * heap and returns a pointer to it 00223 * 00224 * Arguments: 00225 * pMemory - pointer to original memory 00226 * dwNewSize - new size to reallocate 00227 * 00228 * Returns: 00229 * Pointer to memory if successful, NULL otherwise 00230 * 00231 ******************************************************************************/ 00232 00233 PVOID 00234 MemReAlloc( 00235 PVOID pMemory, 00236 DWORD dwNewSize 00237 ) 00238 { 00239 return (PVOID)GlobalReAllocPtr(pMemory, dwNewSize, GMEM_ZEROINIT); 00240 } 00241 00242 00243 /****************************************************************************** 00244 * 00245 * MemFree 00246 * 00247 * Function: 00248 * This functions frees memory from the process's heap 00249 * and returns a handle to it. 00250 * 00251 * Arguments: 00252 * pMemory - pointer to memory to free 00253 * 00254 * Returns: 00255 * No return value 00256 * 00257 ******************************************************************************/ 00258 00259 VOID 00260 MemFree( 00261 PVOID pMemory 00262 ) 00263 { 00264 DWORD dwErr; 00265 00266 // 00267 // GlobalFree() resets last error, we get and set around it so we don't 00268 // lose anything we have set. 00269 // 00270 00271 dwErr = GetLastError(); 00272 GlobalFreePtr(pMemory); 00273 if (dwErr) 00274 { 00275 SetLastError(dwErr); 00276 } 00277 } 00278 00279 00280 /****************************************************************************** 00281 * 00282 * MyCopyMemory 00283 * 00284 * Function: 00285 * This functions copies data from one place to another. It takes care 00286 * of overlapping cases. The reason we have our own function and not use 00287 * MoveMemory is that MoveMemory uses memmove which pulls in msvcrt.dll 00288 * 00289 * Arguments: 00290 * pDest - pointer to destination of copy 00291 * pSrc - pointer to source 00292 * dwCount - number of bytes to copy 00293 * 00294 * Returns: 00295 * No return value 00296 * 00297 ******************************************************************************/ 00298 00299 VOID 00300 MyCopyMemory( 00301 PBYTE pDest, 00302 PBYTE pSrc, 00303 DWORD dwCount 00304 ) 00305 { 00306 // 00307 // Make sure overlapping cases are handled 00308 // 00309 00310 if ((pSrc < pDest) && ((pSrc + dwCount) >= pDest)) 00311 { 00312 // 00313 // Overlapping case, copy in reverse 00314 // 00315 00316 pSrc += dwCount - 1; 00317 pDest += dwCount - 1; 00318 00319 while (dwCount--) 00320 { 00321 *pDest-- = *pSrc--; 00322 } 00323 00324 } 00325 else 00326 { 00327 while (dwCount--) 00328 { 00329 *pDest++ = *pSrc++; 00330 } 00331 } 00332 00333 return; 00334 } 00335 00336 00337 /****************************************************************************** 00338 * 00339 * ConvertToUnicode 00340 * 00341 * Function: 00342 * This function converts a given Ansi string to Unicode. It optionally 00343 * allocates memory for the Unicode string which the calling program 00344 * needs to free. 00345 * 00346 * Arguments: 00347 * pszAnsiStr - pointer to Ansi string to convert 00348 * ppwszUnicodeStr - pointer to pointer to Unicode string 00349 * bAllocate - If TRUE, allocate memory for Unicode string 00350 * 00351 * Returns: 00352 * TRUE if successful, FALSE otherwise 00353 * 00354 ******************************************************************************/ 00355 00356 BOOL 00357 ConvertToUnicode( 00358 PCSTR pszAnsiStr, 00359 PWSTR *ppwszUnicodeStr, 00360 BOOL bAllocate 00361 ) 00362 { 00363 DWORD dwLen; // length of Unicode string 00364 00365 dwLen = (lstrlenA(pszAnsiStr) + 1) * sizeof(WCHAR); 00366 00367 // 00368 // Allocate memory for Unicode string 00369 // 00370 00371 if (bAllocate) 00372 { 00373 *ppwszUnicodeStr = (PWSTR)MemAlloc(dwLen); 00374 if (! (*ppwszUnicodeStr)) 00375 { 00376 WARNING((__TEXT("Error allocating memory for Unicode name\n"))); 00377 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00378 return FALSE; 00379 } 00380 } 00381 00382 // 00383 // Convert Ansi string to Unicode 00384 // 00385 00386 if (! MultiByteToWideChar(CP_ACP, 0, pszAnsiStr, -1, 00387 *ppwszUnicodeStr, dwLen)) 00388 { 00389 WARNING((__TEXT("Error converting to Unicode name\n"))); 00390 MemFree(*ppwszUnicodeStr); 00391 *ppwszUnicodeStr = NULL; 00392 return FALSE; 00393 } 00394 00395 return TRUE; 00396 } 00397 00398 00399 /****************************************************************************** 00400 * 00401 * ConvertToAnsi 00402 * 00403 * Function: 00404 * This function converts a given Unicode string to Ansi. It optionally 00405 * allocates memory for the Ansi string which the calling program needs 00406 * to free. 00407 * 00408 * Arguments: 00409 * pwszUnicodeStr - pointer to Unicode string to convert 00410 * ppszAnsiStr - pointer to pointer to Ansi string. 00411 * bAllocate - If TRUE, allocate memory for Ansi string 00412 * 00413 * Returns: 00414 * TRUE if successful, FALSE otherwise 00415 * 00416 ******************************************************************************/ 00417 00418 BOOL 00419 ConvertToAnsi( 00420 PCWSTR pwszUnicodeStr, 00421 PSTR *ppszAnsiStr, 00422 BOOL bAllocate 00423 ) 00424 { 00425 DWORD dwLen; // length of Ansi string 00426 BOOL bUsedDefaultChar; // if default characters were used in 00427 // converting Unicode to Ansi 00428 00429 dwLen = (lstrlenW(pwszUnicodeStr) + 1) * sizeof(char); 00430 00431 // 00432 // Allocate memory for Ansi string 00433 // 00434 00435 if (bAllocate) 00436 { 00437 *ppszAnsiStr = (PSTR)MemAlloc(dwLen); 00438 if (! (*ppszAnsiStr)) 00439 { 00440 WARNING((__TEXT("Error allocating memory for ANSI name\n"))); 00441 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 00442 return FALSE; 00443 } 00444 } 00445 00446 // 00447 // Convert Unicode string to Ansi 00448 // 00449 00450 if (! WideCharToMultiByte(CP_ACP, 0, pwszUnicodeStr, -1, *ppszAnsiStr, 00451 dwLen, NULL, &bUsedDefaultChar) || bUsedDefaultChar) 00452 { 00453 WARNING((__TEXT("Error converting to Ansi name\n"))); 00454 MemFree(*ppszAnsiStr); 00455 *ppszAnsiStr = NULL; 00456 return FALSE; 00457 } 00458 00459 return TRUE; 00460 } 00461 00462 /****************************************************************************** 00463 * 00464 * ValidColorMatchingModule 00465 * 00466 * Function: 00467 * 00468 * Arguments: 00469 * cmmID - ID identifing the CMM 00470 * pCMMDll - pointer to CMM module path and file name 00471 * 00472 * Returns: 00473 * 00474 ******************************************************************************/ 00475 00476 BOOL 00477 ValidColorMatchingModule( 00478 DWORD cmmID, 00479 PTSTR pCMMDll 00480 ) 00481 { 00482 HINSTANCE hInstance = NULL; 00483 DWORD (WINAPI *pfnCMGetInfo)(DWORD); 00484 FARPROC pfnCMRequired; 00485 DWORD i; 00486 BOOL rc = FALSE; // Assume failure 00487 00488 // 00489 // Load the CMM 00490 // 00491 00492 hInstance = LoadLibrary(pCMMDll); 00493 00494 if (!hInstance) 00495 { 00496 WARNING((__TEXT("Could not load CMM %s\n"), pCMMDll)); 00497 goto EndValidColorMatchingModule; 00498 } 00499 00500 (PVOID) pfnCMGetInfo = (PVOID) GetProcAddress(hInstance, gszCMMReqFns[0]); 00501 00502 if (!pfnCMGetInfo) 00503 { 00504 ERR((__TEXT("CMM does not export CMGetInfo\n"))); 00505 goto EndValidColorMatchingModule; 00506 } 00507 00508 // 00509 // Check if the CMM is the right version and reports the same ID 00510 // 00511 00512 if ((pfnCMGetInfo(CMM_VERSION) < 0x00050000) || 00513 (pfnCMGetInfo(CMM_IDENT) != cmmID)) 00514 { 00515 ERR((__TEXT("CMM %s not correct version or reports incorrect ID\n"), pCMMDll)); 00516 goto EndValidColorMatchingModule; 00517 } 00518 00519 // 00520 // Check the remaining required functions is presented 00521 // 00522 00523 for (i=1; i<NUM_REQ_FNS; i++) 00524 { 00525 pfnCMRequired = GetProcAddress(hInstance, gszCMMReqFns[i]); 00526 if (!pfnCMRequired) 00527 { 00528 ERR((__TEXT("CMM %s does not export %s\n"), pCMMDll, gszCMMReqFns[i])); 00529 goto EndValidColorMatchingModule; 00530 } 00531 } 00532 00533 rc = TRUE; 00534 00535 EndValidColorMatchingModule: 00536 00537 if (hInstance) 00538 { 00539 FreeLibrary(hInstance); 00540 } 00541 00542 return rc; 00543 } 00544 00545 00546 /****************************************************************************** 00547 * 00548 * GetColorMatchingModule 00549 * 00550 * Function: 00551 * This functions returns a pointer to a CMMObject corresponding to 00552 * the ID given. It first looks a the list of CMM objects loaded 00553 * into memory, and if it doesn't find the right one, loads it. 00554 * 00555 * Arguments: 00556 * cmmID - ID identifing the CMM 00557 * 00558 * Returns: 00559 * Pointer to the CMM object if successful, NULL otherwise 00560 * 00561 ******************************************************************************/ 00562 00563 PCMMOBJ 00564 GetColorMatchingModule( 00565 DWORD cmmID 00566 ) 00567 { 00568 HANDLE hCMMObj; 00569 PCMMOBJ pCMMObj = NULL; 00570 FARPROC *ppTemp; 00571 HINSTANCE hInstance = NULL; 00572 HKEY hkCMM = NULL; 00573 DWORD dwTaskID; 00574 TCHAR szCMMID[5]; 00575 DWORD dwType, bufSize, i; 00576 TCHAR szBuffer[MAX_PATH]; 00577 BOOL rc = FALSE; // Assume failure 00578 00579 // 00580 // Check if we have already loaded this CMM 00581 // 00582 00583 dwTaskID = GetCurrentProcessId(); 00584 00585 EnterCriticalSection(&critsec); // Critical section 00586 pCMMObj = gpCMMChain; 00587 00588 while (pCMMObj) 00589 { 00590 if ((pCMMObj->dwCMMID == cmmID) && (pCMMObj->dwTaskID == dwTaskID)) 00591 { 00592 pCMMObj->objHdr.dwUseCount++; 00593 break; 00594 } 00595 pCMMObj = pCMMObj->pNext; 00596 } 00597 LeaveCriticalSection(&critsec); // Critical section 00598 00599 if (pCMMObj) 00600 return pCMMObj; 00601 00602 // 00603 // CMM not already loaded - check to see if it is default CMM before 00604 // looking in the registry 00605 // 00606 00607 if (cmmID == CMM_WINDOWS_DEFAULT) 00608 { 00609 hInstance = LoadLibrary(gszDefaultCMM); 00610 goto AttemptedLoadingCMM; 00611 } 00612 00613 // 00614 // Not default CMM, look in the registry 00615 // 00616 00617 if (RegOpenKey(HKEY_LOCAL_MACHINE, gszICMatcher, &hkCMM) != ERROR_SUCCESS) 00618 { 00619 return NULL; 00620 } 00621 00622 // 00623 // Make a string with the CMM ID 00624 // 00625 00626 #ifdef UNICODE 00627 { 00628 DWORD temp = FIX_ENDIAN(cmmID); 00629 00630 if (!MultiByteToWideChar(CP_ACP, 0, (PSTR)&temp, 4, szCMMID, 5)) 00631 { 00632 WARNING((__TEXT("Could not convert cmmID %x to Unicode\n"), temp)); 00633 goto EndGetColorMatchingModule; 00634 } 00635 } 00636 #else 00637 for (i=0; i<4; i++) 00638 { 00639 szCMMID[i] = ((PSTR)&cmmID)[3-i]; 00640 } 00641 #endif 00642 szCMMID[4] = '\0'; 00643 00644 // 00645 // Get the file name of the CMM dll if registered 00646 // 00647 00648 bufSize = MAX_PATH; 00649 if (RegQueryValueEx(hkCMM, (PTSTR)szCMMID, 0, &dwType, (BYTE *)szBuffer, &bufSize) != 00650 ERROR_SUCCESS) 00651 { 00652 WARNING((__TEXT("CMM %s not registered\n"), szCMMID)); 00653 goto EndGetColorMatchingModule; 00654 } 00655 00656 // 00657 // Load the CMM 00658 // 00659 00660 hInstance = LoadLibrary(szBuffer); 00661 00662 AttemptedLoadingCMM: 00663 00664 if (!hInstance) 00665 { 00666 WARNING((__TEXT("Could not load CMM %x\n"), cmmID)); 00667 goto EndGetColorMatchingModule; 00668 } 00669 00670 // 00671 // Allocate a CMM object 00672 // 00673 00674 hCMMObj = AllocateHeapObject(OBJ_CMM); 00675 if (!hCMMObj) 00676 { 00677 ERR((__TEXT("Could not allocate CMM object\n"))); 00678 goto EndGetColorMatchingModule; 00679 } 00680 00681 pCMMObj = (PCMMOBJ)HDLTOPTR(hCMMObj); 00682 00683 ASSERT(pCMMObj != NULL); 00684 00685 // 00686 // Fill in the CMM object 00687 // 00688 00689 pCMMObj->objHdr.dwUseCount = 1; 00690 pCMMObj->dwCMMID = cmmID; 00691 pCMMObj->dwTaskID = dwTaskID; 00692 pCMMObj->hCMM = hInstance; 00693 00694 ppTemp = (FARPROC *)&pCMMObj->fns.pCMGetInfo; 00695 *ppTemp = GetProcAddress(hInstance, gszCMMReqFns[0]); 00696 ppTemp++; 00697 00698 if (!pCMMObj->fns.pCMGetInfo) 00699 { 00700 ERR((__TEXT("CMM does not export CMGetInfo\n"))); 00701 goto EndGetColorMatchingModule; 00702 } 00703 00704 // 00705 // Check if the CMM is the right version and reports the same ID 00706 // 00707 00708 if (pCMMObj->fns.pCMGetInfo(CMM_VERSION) < 0x00050000 || 00709 pCMMObj->fns.pCMGetInfo(CMM_IDENT) != cmmID) 00710 { 00711 ERR((__TEXT("CMM not correct version or reports incorrect ID\n"))); 00712 goto EndGetColorMatchingModule; 00713 } 00714 00715 // 00716 // Load the remaining required functions 00717 // 00718 00719 for (i=1; i<NUM_REQ_FNS; i++) 00720 { 00721 *ppTemp = GetProcAddress(hInstance, gszCMMReqFns[i]); 00722 if (!*ppTemp) 00723 { 00724 ERR((__TEXT("CMM %s does not export %s\n"), szCMMID, gszCMMReqFns[i])); 00725 goto EndGetColorMatchingModule; 00726 } 00727 ppTemp++; 00728 } 00729 00730 // 00731 // Load the optional functions 00732 // 00733 00734 for (i=0; i<NUM_OPT_FNS; i++) 00735 { 00736 *ppTemp = GetProcAddress(hInstance, gszCMMOptFns[i]); 00737 00738 // 00739 // Even these functions are required for Windows default CMM 00740 // 00741 00742 if (cmmID == CMM_WINDOWS_DEFAULT && !*ppTemp) 00743 { 00744 ERR((__TEXT("Windows default CMM does not export %s\n"), gszCMMOptFns[i])); 00745 goto EndGetColorMatchingModule; 00746 } 00747 ppTemp++; 00748 } 00749 00750 // 00751 // Load the PS functions - these are optional even for the default CMM 00752 // 00753 00754 for (i=0; i<NUM_PS_FNS; i++) 00755 { 00756 *ppTemp = GetProcAddress(hInstance, gszPSFns[i]); 00757 ppTemp++; 00758 } 00759 00760 // 00761 // If any of the PS Level2 fns is not exported, do not use this CMM 00762 // for any of the PS Level 2 functionality 00763 // 00764 00765 if (!pCMMObj->fns.pCMGetPS2ColorSpaceArray || 00766 !pCMMObj->fns.pCMGetPS2ColorRenderingIntent || 00767 !pCMMObj->fns.pCMGetPS2ColorRenderingDictionary) 00768 { 00769 pCMMObj->fns.pCMGetPS2ColorSpaceArray = NULL; 00770 pCMMObj->fns.pCMGetPS2ColorRenderingIntent = NULL; 00771 pCMMObj->fns.pCMGetPS2ColorRenderingDictionary = NULL; 00772 pCMMObj->dwFlags |= CMM_DONT_USE_PS2_FNS; 00773 } 00774 00775 // 00776 // Add the CMM object to the chain at the beginning 00777 // 00778 00779 EnterCriticalSection(&critsec); // Critical section 00780 pCMMObj->pNext = gpCMMChain; 00781 gpCMMChain = pCMMObj; 00782 LeaveCriticalSection(&critsec); // Critical section 00783 00784 rc = TRUE; // Success! 00785 00786 EndGetColorMatchingModule: 00787 00788 if (!rc) 00789 { 00790 if (pCMMObj) 00791 { 00792 pCMMObj->objHdr.dwUseCount--; // decrement before freeing 00793 FreeHeapObject(hCMMObj); 00794 pCMMObj = NULL; 00795 } 00796 if (hInstance) 00797 { 00798 FreeLibrary(hInstance); 00799 } 00800 } 00801 00802 if (hkCMM) 00803 { 00804 RegCloseKey(hkCMM); 00805 } 00806 00807 return pCMMObj; 00808 } 00809 00810 00811 /****************************************************************************** 00812 * 00813 * GetPreferredCMM 00814 * 00815 * Function: 00816 * This functions returns a pointer to the app specified CMM to use 00817 * 00818 * Arguments: 00819 * None 00820 * 00821 * Returns: 00822 * Pointer to app specified CMM object on success, NULL otherwise 00823 * 00824 ******************************************************************************/ 00825 00826 PCMMOBJ GetPreferredCMM( 00827 ) 00828 { 00829 PCMMOBJ pCMMObj; 00830 00831 EnterCriticalSection(&critsec); // Critical section 00832 pCMMObj = gpPreferredCMM; 00833 00834 if (pCMMObj) 00835 { 00836 // 00837 // Increment use count 00838 // 00839 00840 pCMMObj->objHdr.dwUseCount++; 00841 } 00842 LeaveCriticalSection(&critsec); // Critical section 00843 00844 return pCMMObj; 00845 } 00846 00847 00848 /****************************************************************************** 00849 * 00850 * ReleaseColorMatchingModule 00851 * 00852 * Function: 00853 * This functions releases a CMM object. If the ref count goes to 00854 * zero, it unloads the CMM and frees all memory associated with it. 00855 * 00856 * Arguments: 00857 * pCMMObj - pointer to CMM object to release 00858 * 00859 * Returns: 00860 * No return value 00861 * 00862 ******************************************************************************/ 00863 00864 VOID 00865 ReleaseColorMatchingModule( 00866 PCMMOBJ pCMMObj 00867 ) 00868 { 00869 EnterCriticalSection(&critsec); // Critical section 00870 00871 ASSERT(pCMMObj->objHdr.dwUseCount > 0); 00872 00873 pCMMObj->objHdr.dwUseCount--; 00874 00875 if (pCMMObj->objHdr.dwUseCount == 0) 00876 { 00877 // 00878 // Unloading the CMM everytime a transform is freed might not be 00879 // very efficient. So for now, I am not going to unload it. When 00880 // the app terminates, kernel should unload all dll's loaded by 00881 // this app 00882 // 00883 } 00884 LeaveCriticalSection(&critsec); // Critical section 00885 00886 return; 00887 } 00888 00889 00890 #ifdef DBG 00891 00892 /****************************************************************************** 00893 * 00894 * MyDebugPrint 00895 * 00896 * Function: 00897 * This function takes a format string and paramters, composes a string 00898 * and sends it out to the debug port. Available only in debug build. 00899 * 00900 * Arguments: 00901 * pFormat - pointer to format string 00902 * ....... - parameters based on the format string like printf() 00903 * 00904 * Returns: 00905 * No return value 00906 * 00907 ******************************************************************************/ 00908 00909 VOID 00910 MyDebugPrintA( 00911 PSTR pFormat, 00912 ... 00913 ) 00914 { 00915 char szBuffer[256]; 00916 va_list arglist; 00917 00918 va_start(arglist, pFormat); 00919 wvsprintfA(szBuffer, pFormat, arglist); 00920 va_end(arglist); 00921 00922 OutputDebugStringA(szBuffer); 00923 00924 return; 00925 } 00926 00927 00928 VOID 00929 MyDebugPrintW( 00930 PWSTR pFormat, 00931 ... 00932 ) 00933 { 00934 WCHAR szBuffer[256]; 00935 va_list arglist; 00936 00937 va_start(arglist, pFormat); 00938 wvsprintfW(szBuffer, pFormat, arglist); 00939 va_end(arglist); 00940 00941 OutputDebugStringW(szBuffer); 00942 00943 return; 00944 } 00945 00946 /****************************************************************************** 00947 * 00948 * StripDirPrefixA 00949 * 00950 * Function: 00951 * This function takes a path name and returns a pointer to the filename 00952 * part. This is availabel only for the debug build. 00953 * 00954 * Arguments: 00955 * pszPathName - path name of file (can be file name alone) 00956 * 00957 * Returns: 00958 * A pointer to the file name 00959 * 00960 ******************************************************************************/ 00961 00962 PSTR 00963 StripDirPrefixA( 00964 PSTR pszPathName 00965 ) 00966 { 00967 DWORD dwLen = lstrlenA(pszPathName); 00968 00969 pszPathName += dwLen - 1; // go to the end 00970 00971 while (*pszPathName != '\\' && dwLen--) 00972 { 00973 pszPathName--; 00974 } 00975 00976 return pszPathName + 1; 00977 } 00978 00979 #endif 00980

Generated on Sat May 15 19:41:05 2004 for test by doxygen 1.3.7