void RemoveTegIDKey(guint iKeyType, GnAnimationKeyManager* pAnimationKeyManager, guint uiIndex) { GnAssert( iKeyType == GnAnimationKey::TEGIDKEY ); GnAnimationKeyManager::AniKey useKey; int keyIndex = GetAniKey( iKeyType, pAnimationKeyManager, useKey ); if( keyIndex == -1 ) { return; } guint32 numKey = useKey.mNumKey; useKey.mNumKey -= 1; if( useKey.mNumKey <= 0 ) { DeleteKeys(iKeyType, pAnimationKeyManager, useKey); return; } GnTegIDKey* useTegIDKey = (GnTegIDKey*)useKey.mAnimationKeys; for( gtuint i = uiIndex, fill = uiIndex + 1; fill < numKey ; i++, fill++ ) { useTegIDKey[i] = useTegIDKey[fill]; } pAnimationKeyManager->GetAnimationKeys()->SetAt( keyIndex, useKey ); }
int CFreeLists::FindBlock(SHORT nHandle, DWORD dwBlockSize, DWORD * pdwFoundOffset) { int nFindRetVal, nRetVal; DWORD dwCurrentBlockSize, dwOffset, dwNewBlockSize, dwNewOffset; COffsetKey offsetKey; ASSERT(pdwFoundOffset); if(pdwFoundOffset == NULL) return ERRORCODE_BadParameter; nFindRetVal = m_pIndexFile->Find( dwBlockSize, // Key is block size NULL, 0, // No data associated with key 0, // Don't know offset (record #) so supply 0 nHandle); // Index file ID if(nFindRetVal != CCIndexFile::success && nFindRetVal != CCIndexFile::keyMatch && nFindRetVal != CCIndexFile::keyGreaterFound) return ERRORCODE_Fail; nRetVal = m_pIndexFile->GetCurrentKey(&dwCurrentBlockSize); // We should be able to get current key since find was successful if(nRetVal != CCIndexFile::success) CCIndexFileException::Throw(nRetVal); dwOffset = m_pIndexFile->GetRecordNum(); *pdwFoundOffset = dwOffset; // Delete keys thus freeing up block for client to use nRetVal = DeleteKeys( nHandle, dwCurrentBlockSize, dwOffset, FALSE, // Find block key TRUE); // Find offset key if(nRetVal != CCIndexFile::success) CCIndexFileException::Throw(nRetVal); // If requested block size doesn't exactly match requested (Most cases), // Use it anyway by breaking up into 2 blocks with // 1st block matching requested size and second block is remainder // 1st block is marked as free if(nFindRetVal == CCIndexFile::keyGreaterFound) { dwNewBlockSize = dwCurrentBlockSize - dwBlockSize; dwNewOffset = dwOffset + dwBlockSize; nRetVal = AddBlock(nHandle, dwNewBlockSize, dwNewOffset); // Should always be able to add ASSERT(nRetVal == ERRORCODE_None); } return ERRORCODE_None; }
int CFreeLists::AddBlock(SHORT nHandle, DWORD dwBlockSize, DWORD dwOffset) { int nRetVal; BOOL bPrevBlockMatch=FALSE, bNearMatchBlock=FALSE; DWORD dwPrevOffset, dwPrevBlockSize, dwNearOffset, dwNearBlockSize; DWORD dwNextBlockOffset,dwPrevBlockOffset; DWORD dwNewBlockSize=dwBlockSize, dwNewOffset=dwOffset; COffsetKey offsetKey; // Try to locate the nearest block to the one we are about to add // Check if nearest match has a block that is sequential // to block we are about to add offsetKey.SetOffset(dwOffset); offsetKey.SetID(nHandle); // Find() will locate keys containing the next positional item // when an exact match doesn't occur nRetVal = m_pIndexFile->Find( &offsetKey, // Special user defined key NULL, 0, // No data associated with key 0, // Don't know Block Size (record #) so supply 0 SORTED_BY_OFFSET_INDEX); // Index file ID if(nRetVal == CCIndexFile::success || nRetVal == CCIndexFile::keyMatch || nRetVal == CCIndexFile::keyGreaterFound) { // Found OFFSET key, check if sequential nRetVal = m_pIndexFile->GetCurrentKey((LPVOID)&offsetKey); // We should be able to get current key since find was successful if(nRetVal != CCIndexFile::success) CCIndexFileException::Throw(nRetVal); dwNearBlockSize = m_pIndexFile->GetRecordNum(); // What is the next block of the block we are about to add dwNextBlockOffset = dwOffset + dwBlockSize; // Does the beginning position of the next block of the block // we are about to add match the beginning position of the // nearest match dwNearOffset = offsetKey.GetOffset(); if(dwNextBlockOffset == dwNearOffset) { bNearMatchBlock = TRUE; // Block size grows, but Offset stays the same dwNewBlockSize += dwNearBlockSize; // Delete near match key since we're merging blocks // We should be able to delete current offset key // since find was successful nRetVal = DeleteKeys( nHandle, dwNearBlockSize, dwNearOffset, TRUE, // Find block key FALSE); // Find offset key if(nRetVal != CCIndexFile::success) CCIndexFileException::Throw(nRetVal); } // Get previous index entry of near match which represents // previous free block of near match nRetVal = m_pIndexFile->GetPrevEntry(NULL, NULL, SORTED_BY_OFFSET_INDEX); if(nRetVal == CCIndexFile::success) { nRetVal = m_pIndexFile->GetCurrentKey((LPVOID)&offsetKey); // We should be able to get current key since find was successful if(nRetVal != CCIndexFile::success) CCIndexFileException::Throw(nRetVal); dwPrevBlockSize = m_pIndexFile->GetRecordNum(); // What is the previous blocks next block dwPrevOffset = offsetKey.GetOffset(); dwPrevBlockOffset = dwPrevOffset + dwPrevBlockSize; // Does its position match the one we are about to add? // (and ID matches) if(dwPrevBlockOffset == dwOffset && offsetKey.GetID() == nHandle) { // It matched, delete it since we are going // to merge free blocks bPrevBlockMatch = TRUE; dwNewBlockSize += dwPrevBlockSize; dwNewOffset -= dwPrevBlockSize; // Should Match prev offset ASSERT(dwNewOffset == dwPrevOffset); // Delete prev offset key since we're merging blocks nRetVal = DeleteKeys( nHandle, dwPrevBlockSize, dwPrevOffset, TRUE, // Find block key FALSE); // Find offset key if(nRetVal != CCIndexFile::success) CCIndexFileException::Throw(nRetVal); } } } else { // Since no greater than key was found, get last and check // if it is sequentially positioned before new block nRetVal = m_pIndexFile->GetLastEntry(NULL, NULL, SORTED_BY_OFFSET_INDEX); if(nRetVal == CCIndexFile::success) { nRetVal = m_pIndexFile->GetCurrentKey((LPVOID)&offsetKey); // We should be able to get current key since find was successful if(nRetVal != CCIndexFile::success) CCIndexFileException::Throw(nRetVal); dwPrevBlockSize = m_pIndexFile->GetRecordNum(); // What is the previous blocks next block dwPrevOffset = offsetKey.GetOffset(); dwPrevBlockOffset = dwPrevOffset + dwPrevBlockSize; // Does its position match the one we are about to add? if(dwPrevBlockOffset == dwOffset && offsetKey.GetID() == nHandle) { // It matched, delete it since we are going // to merge free blocks bPrevBlockMatch = TRUE; dwNewBlockSize += dwPrevBlockSize; dwNewOffset -= dwPrevBlockSize; // Should Match prev offset ASSERT(dwNewOffset == dwPrevOffset); // Delete prev offset key since we're merging blocks nRetVal = DeleteKeys( nHandle, dwPrevBlockSize, dwPrevOffset, TRUE, // Find block key FALSE); // Find offset key if(nRetVal != CCIndexFile::success) CCIndexFileException::Throw(nRetVal); } } } offsetKey.SetOffset(dwNewOffset); offsetKey.SetID(nHandle); nRetVal = m_pIndexFile->Add( dwNewBlockSize,// Key is block size NULL, 0, // No data associated with key dwNewOffset, // Use record # to store offset to free block nHandle, // Index file ID TRUE); // Allow duplicate keys // Throw exception if CIndex failed to add key // File is probably not open if(nRetVal != CCIndexFile::success) CCIndexFileException::Throw(nRetVal); // Add key of Offset Index which may represent combined blocks nRetVal = m_pIndexFile->Add( (LPVOID)&offsetKey, // Key is block size NULL, 0, // No data associated with key dwNewBlockSize, // Use record # to store block size SORTED_BY_OFFSET_INDEX, // Index file ID FALSE); // Should never have duplicate keys // Throw exception if CIndex failed to add key // File is probably not open if(nRetVal != CCIndexFile::success) CCIndexFileException::Throw(nRetVal); return ERRORCODE_None; }
/****************************************************************************++ Routine Description: Creates a handle to the CSP Arguments: pwzContainerName - name of the container to be created. if NULL, GUID is generated for the name of the container fCreateNewKeys - forces new keys to be created phCryptProv - pointer to the location, where handle should be returned Notes: - Return Value: - S_OK - or - - CAPI error returned by CryptAcquireContextW --*****************************************************************************/ HRESULT CreateCryptProv( IN PCWSTR pwzContainerName, IN BOOL fCreateNewKeys, OUT HCRYPTPROV* phCryptProv) { HRESULT hr = S_OK; HCRYPTKEY hKey = NULL; RPC_STATUS status = RPC_S_OK; BOOL fCreatedContainer = FALSE; WCHAR* pwzNewContainerName = NULL; *phCryptProv = NULL; if (NULL == pwzContainerName) { UUID uuid; BOOL fServiceAccount = FALSE; // // generate container name from the UUID // status = UuidCreate(&uuid); hr = HRESULT_FROM_RPCSTATUS(status); if (FAILED(hr)) { goto Cleanup; } status = UuidToStringW(&uuid, (unsigned short**)&pwzNewContainerName); hr = HRESULT_FROM_RPCSTATUS(status); if (FAILED(hr)) { goto Cleanup; } pwzContainerName = pwzNewContainerName; hr = IsServiceAccount(&fServiceAccount); if (FAILED(hr)) { goto Cleanup; } // // open the clean key container // // note: CRYPT_NEW_KEYSET is not creating new keys, it just // creates new key container. duh. // if (!CryptAcquireContextW(phCryptProv, pwzNewContainerName, NULL, // default provider name DEFAULT_PROV_TYPE, fServiceAccount ? (CRYPT_SILENT | CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET) : (CRYPT_SILENT | CRYPT_NEWKEYSET))) { hr = HRESULT_FROM_WIN32(GetLastError()); // // we are seeing that CryptAcquireContextW returns NTE_FAIL under low // memory condition, so we just mask the error // if (NTE_FAIL == hr) { hr = E_OUTOFMEMORY; } goto Cleanup; } fCreatedContainer = TRUE; } else { BOOL fServiceAccount = FALSE; hr = IsServiceAccount(&fServiceAccount); if (FAILED(hr)) { goto Cleanup; } // // open the provider first, create the keys too // if (!CryptAcquireContextW(phCryptProv, pwzContainerName, NULL, // default provider name DEFAULT_PROV_TYPE, fServiceAccount ? (CRYPT_SILENT | CRYPT_MACHINE_KEYSET) : (CRYPT_SILENT))) { hr = HRESULT_FROM_WIN32(GetLastError()); // // we are seeing that CryptAcquireContextW returns NTE_FAIL under low // memory condition, so we just mask the error // if (NTE_FAIL == hr) { hr = E_OUTOFMEMORY; } goto Cleanup; } } if (fCreateNewKeys) { // // make sure keys exist // if (!CryptGetUserKey(*phCryptProv, DEFAULT_KEY_SPEC, &hKey)) { hr = HRESULT_FROM_WIN32(GetLastError()); // if key does not exist, create it if (HRESULT_FROM_WIN32((unsigned long)NTE_NO_KEY) == hr) { hr = S_OK; if (!CryptGenKey(*phCryptProv, DEFAULT_KEY_SPEC, CRYPT_EXPORTABLE, &hKey)) { hr = HRESULT_FROM_WIN32(GetLastError()); // // we are seeing that CryptGenKey returns ERROR_CANTOPEN under low // memory condition, so we just mask the error // if (HRESULT_FROM_WIN32(ERROR_CANTOPEN) == hr) { hr = E_OUTOFMEMORY; } goto Cleanup; } } else { // failed to get user key by some misterious reason, so bail out goto Cleanup; } } } Cleanup: DestroyKey(hKey); if (FAILED(hr)) { // // release the context // ReleaseCryptProv(*phCryptProv); *phCryptProv = NULL; // // delete the keys, if we created them // if (fCreatedContainer) { DeleteKeys(pwzContainerName); } } if (NULL != pwzNewContainerName) { // this always returns RPC_S_OK status = RpcStringFreeW((unsigned short**)&pwzNewContainerName); USES(status); } return hr; }