⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 storage32.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 5 页
字号:
  propertyToDelete.sizeOfNameString = 0;

  /*
   * Here we should re-read the property so we get the updated pointer
   * but since we are here to zap it, I don't do it...
   */
  StorageImpl_WriteProperty(
    parentStorage->base.ancestorStorage,
    indexOfPropertyToDelete,
    &propertyToDelete);

  return S_OK;
}

/*********************************************************************
 *
 * Internal Method
 *
 * Finds a placeholder for the StgProperty within the Storage
 *
 */
static HRESULT findPlaceholder(
  StorageImpl *storage,
  ULONG         propertyIndexToStore,
  ULONG         storePropertyIndex,
  INT         typeOfRelation)
{
  StgProperty storeProperty;
  HRESULT     hr = S_OK;
  BOOL      res = TRUE;

  /*
   * Read the storage property
   */
  res = StorageImpl_ReadProperty(
          storage->base.ancestorStorage,
          storePropertyIndex,
          &storeProperty);

  if(! res)
  {
    return E_FAIL;
  }

  if (typeOfRelation == PROPERTY_RELATION_PREVIOUS)
  {
    if (storeProperty.previousProperty != PROPERTY_NULL)
    {
      return findPlaceholder(
               storage,
               propertyIndexToStore,
               storeProperty.previousProperty,
               typeOfRelation);
    }
    else
    {
      storeProperty.previousProperty = propertyIndexToStore;
    }
  }
  else if (typeOfRelation == PROPERTY_RELATION_NEXT)
  {
    if (storeProperty.nextProperty != PROPERTY_NULL)
    {
      return findPlaceholder(
               storage,
               propertyIndexToStore,
               storeProperty.nextProperty,
               typeOfRelation);
    }
    else
    {
      storeProperty.nextProperty = propertyIndexToStore;
    }
  }
  else if (typeOfRelation == PROPERTY_RELATION_DIR)
  {
    if (storeProperty.dirProperty != PROPERTY_NULL)
    {
      return findPlaceholder(
               storage,
               propertyIndexToStore,
               storeProperty.dirProperty,
               typeOfRelation);
    }
    else
    {
      storeProperty.dirProperty = propertyIndexToStore;
    }
  }

  hr = StorageImpl_WriteProperty(
         storage->base.ancestorStorage,
         storePropertyIndex,
         &storeProperty);

  if(! hr)
  {
    return E_FAIL;
  }

  return S_OK;
}

/*************************************************************************
 *
 * Internal Method
 *
 * This method takes the previous and the next property link of a property
 * to be deleted and find them a place in the Storage.
 */
static HRESULT adjustPropertyChain(
  StorageImpl *This,
  StgProperty   propertyToDelete,
  StgProperty   parentProperty,
  ULONG         parentPropertyId,
  INT         typeOfRelation)
{
  ULONG   newLinkProperty        = PROPERTY_NULL;
  BOOL  needToFindAPlaceholder = FALSE;
  ULONG   storeNode              = PROPERTY_NULL;
  ULONG   toStoreNode            = PROPERTY_NULL;
  INT   relationType           = 0;
  HRESULT hr                     = S_OK;
  BOOL  res                    = TRUE;

  if (typeOfRelation == PROPERTY_RELATION_PREVIOUS)
  {
    if (propertyToDelete.previousProperty != PROPERTY_NULL)
    {
      /*
       * Set the parent previous to the property to delete previous
       */
      newLinkProperty = propertyToDelete.previousProperty;

      if (propertyToDelete.nextProperty != PROPERTY_NULL)
      {
        /*
         * We also need to find a storage for the other link, setup variables
         * to do this at the end...
         */
        needToFindAPlaceholder = TRUE;
        storeNode              = propertyToDelete.previousProperty;
        toStoreNode            = propertyToDelete.nextProperty;
        relationType           = PROPERTY_RELATION_NEXT;
      }
    }
    else if (propertyToDelete.nextProperty != PROPERTY_NULL)
    {
      /*
       * Set the parent previous to the property to delete next
       */
      newLinkProperty = propertyToDelete.nextProperty;
    }

    /*
     * Link it for real...
     */
    parentProperty.previousProperty = newLinkProperty;

  }
  else if (typeOfRelation == PROPERTY_RELATION_NEXT)
  {
    if (propertyToDelete.previousProperty != PROPERTY_NULL)
    {
      /*
       * Set the parent next to the property to delete next previous
       */
      newLinkProperty = propertyToDelete.previousProperty;

      if (propertyToDelete.nextProperty != PROPERTY_NULL)
      {
        /*
         * We also need to find a storage for the other link, setup variables
         * to do this at the end...
         */
        needToFindAPlaceholder = TRUE;
        storeNode              = propertyToDelete.previousProperty;
        toStoreNode            = propertyToDelete.nextProperty;
        relationType           = PROPERTY_RELATION_NEXT;
      }
    }
    else if (propertyToDelete.nextProperty != PROPERTY_NULL)
    {
      /*
       * Set the parent next to the property to delete next
       */
      newLinkProperty = propertyToDelete.nextProperty;
    }

    /*
     * Link it for real...
     */
    parentProperty.nextProperty = newLinkProperty;
  }
  else /* (typeOfRelation == PROPERTY_RELATION_DIR) */
  {
    if (propertyToDelete.previousProperty != PROPERTY_NULL)
    {
      /*
       * Set the parent dir to the property to delete previous
       */
      newLinkProperty = propertyToDelete.previousProperty;

      if (propertyToDelete.nextProperty != PROPERTY_NULL)
      {
        /*
         * We also need to find a storage for the other link, setup variables
         * to do this at the end...
         */
        needToFindAPlaceholder = TRUE;
        storeNode              = propertyToDelete.previousProperty;
        toStoreNode            = propertyToDelete.nextProperty;
        relationType           = PROPERTY_RELATION_NEXT;
      }
    }
    else if (propertyToDelete.nextProperty != PROPERTY_NULL)
    {
      /*
       * Set the parent dir to the property to delete next
       */
      newLinkProperty = propertyToDelete.nextProperty;
    }

    /*
     * Link it for real...
     */
    parentProperty.dirProperty = newLinkProperty;
  }

  /*
   * Write back the parent property
   */
  res = StorageImpl_WriteProperty(
          This->base.ancestorStorage,
          parentPropertyId,
          &parentProperty);
  if(! res)
  {
    return E_FAIL;
  }

  /*
   * If a placeholder is required for the other link, then, find one and
   * get out of here...
   */
  if (needToFindAPlaceholder)
  {
    hr = findPlaceholder(
           This,
           toStoreNode,
           storeNode,
           relationType);
  }

  return hr;
}


/******************************************************************************
 * SetElementTimes (IStorage)
 */
HRESULT WINAPI StorageImpl_SetElementTimes(
  IStorage*     iface,
  const OLECHAR *pwcsName,/* [string][in] */
  const FILETIME  *pctime,  /* [in] */
  const FILETIME  *patime,  /* [in] */
  const FILETIME  *pmtime)  /* [in] */
{
  FIXME("(%s,...), stub!\n",debugstr_w(pwcsName));
  return S_OK;
}

/******************************************************************************
 * SetStateBits (IStorage)
 */
HRESULT WINAPI StorageImpl_SetStateBits(
  IStorage*   iface,
  DWORD         grfStateBits,/* [in] */
  DWORD         grfMask)     /* [in] */
{
  FIXME("not implemented!\n");
  return E_NOTIMPL;
}

/*
 * Virtual function table for the IStorage32Impl class.
 */
static const IStorageVtbl Storage32Impl_Vtbl =
{
    StorageBaseImpl_QueryInterface,
    StorageBaseImpl_AddRef,
    StorageBaseImpl_Release,
    StorageBaseImpl_CreateStream,
    StorageBaseImpl_OpenStream,
    StorageImpl_CreateStorage,
    StorageBaseImpl_OpenStorage,
    StorageImpl_CopyTo,
    StorageImpl_MoveElementTo,
    StorageImpl_Commit,
    StorageImpl_Revert,
    StorageBaseImpl_EnumElements,
    StorageImpl_DestroyElement,
    StorageBaseImpl_RenameElement,
    StorageImpl_SetElementTimes,
    StorageBaseImpl_SetClass,
    StorageImpl_SetStateBits,
    StorageImpl_Stat
};

HRESULT StorageImpl_Construct(
  StorageImpl* This,
  HANDLE       hFile,
  LPCOLESTR    pwcsName,
  ILockBytes*  pLkbyt,
  DWORD        openFlags,
  BOOL         fileBased,
  BOOL         fileCreate)
{
  HRESULT     hr = S_OK;
  StgProperty currentProperty;
  BOOL      readSuccessful;
  ULONG       currentPropertyIndex;

  if ( FAILED( validateSTGM(openFlags) ))
    return STG_E_INVALIDFLAG;

  memset(This, 0, sizeof(StorageImpl));

  /*
   * Initialize the virtual function table.
   */
  This->base.lpVtbl = &Storage32Impl_Vtbl;
  This->base.pssVtbl = &IPropertySetStorage_Vtbl;
  This->base.v_destructor = &StorageImpl_Destroy;
  This->base.openFlags = openFlags;

  /*
   * This is the top-level storage so initialize the ancestor pointer
   * to this.
   */
  This->base.ancestorStorage = This;

  /*
   * Initialize the physical support of the storage.
   */
  This->hFile = hFile;

  /*
   * Store copy of file path.
   */
  if(pwcsName) {
      This->pwcsName = HeapAlloc(GetProcessHeap(), 0,
                                (lstrlenW(pwcsName)+1)*sizeof(WCHAR));
      if (!This->pwcsName)
         return STG_E_INSUFFICIENTMEMORY;
      strcpyW(This->pwcsName, pwcsName);
  }

  /*
   * Initialize the big block cache.
   */
  This->bigBlockSize   = DEF_BIG_BLOCK_SIZE;
  This->smallBlockSize = DEF_SMALL_BLOCK_SIZE;
  This->bigBlockFile   = BIGBLOCKFILE_Construct(hFile,
                                                pLkbyt,
                                                openFlags,
                                                This->bigBlockSize,
                                                fileBased);

  if (This->bigBlockFile == 0)
    return E_FAIL;

  if (fileCreate)
  {
    ULARGE_INTEGER size;
    BYTE* bigBlockBuffer;

    /*
     * Initialize all header variables:
     * - The big block depot consists of one block and it is at block 0
     * - The properties start at block 1
     * - There is no small block depot
     */
    memset( This->bigBlockDepotStart,
            BLOCK_UNUSED,
            sizeof(This->bigBlockDepotStart));

    This->bigBlockDepotCount    = 1;
    This->bigBlockDepotStart[0] = 0;
    This->rootStartBlock        = 1;
    This->smallBlockDepotStart  = BLOCK_END_OF_CHAIN;
    This->bigBlockSizeBits      = DEF_BIG_BLOCK_SIZE_BITS;
    This->smallBlockSizeBits    = DEF_SMALL_BLOCK_SIZE_BITS;
    This->extBigBlockDepotStart = BLOCK_END_OF_CHAIN;
    This->extBigBlockDepotCount = 0;

    StorageImpl_SaveFileHeader(This);

    /*
     * Add one block for the big block depot and one block for the properties
     */
    size.u.HighPart = 0;
    size.u.LowPart  = This->bigBlockSize * 3;
    BIGBLOCKFILE_SetSize(This->bigBlockFile, size);

    /*
     * Initialize the big block depot
     */
    bigBlockBuffer = StorageImpl_GetBigBlock(This, 0);
    memset(bigBlockBuffer, BLOCK_UNUSED, This->bigBlockSize);
    StorageUtl_WriteDWord(bigBlockBuffer, 0, BLOCK_SPECIAL);
    StorageUtl_WriteDWord(bigBlockBuffer, sizeof(ULONG), BLOCK_END_OF_CHAIN);
    StorageImpl_ReleaseBigBlock(This, bigBlockBuffer);
  }
  else
  {
    /*
     * Load the header for the file.
     */
    hr = StorageImpl_LoadFileHeader(This);

    if (FAILED(hr))
    {
      BIGBLOCKFILE_Destructor(This->bigBlockFile);

      return hr;
    }
  }

  /*
   * There is no block depot cached yet.
   */
  This->indexBlockDepotCached = 0xFFFFFFFF;

  /*
   * Start searching for free blocks with block 0.
   */
  This->prevFreeBlock = 0;

  /*
   * Create the block chain abstractions.
   */
  if(!(This->rootBlockChain =
       BlockChainStream_Construct(This, &This->rootStartBlock, PROPERTY_NULL)))
    return STG_E_READFAULT;

  if(!(This->smallBlockDepotChain =
       BlockChainStream_Construct(This, &This->smallBlockDepotStart,
				  PROPERTY_NULL)))
    return STG_E_READFAULT;

  /*
   * Write the root property
   */
  if (fileCreate)
  {
    StgProperty rootProp;
    /*
     * Initialize the property chain
     */
    memset(&rootProp, 0, sizeof(rootProp));
    MultiByteToWideChar( CP_ACP, 0, rootPropertyName, -1, rootProp.name,
                         sizeof(rootProp.name)/sizeof(WCHAR) );
    rootProp.sizeOfNameString = (strlenW(rootProp.name)+1) * sizeof(WCHAR);
    rootProp.propertyType     = PROPTYPE_ROOT;
    rootProp.previousProperty = PROPERTY_NULL;
    rootProp.nextProperty     = PROPERTY_NULL;
    rootProp.dirProperty      = PROPERTY_NULL;
    rootProp.startingBlock    = BLOCK_END_OF_CHAIN;
    rootProp.size.u.HighPart    = 0;
    rootProp.size.u.LowPart     = 0;

    StorageImpl_WriteProperty(This, 0, &rootProp);
  }

  /*
   * Find the ID of t

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -