示例#1
0
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 );
}
示例#2
0
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;
   }
示例#3
0
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;
}