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

📄 storage32.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
   */
  propertyEnumeration = IEnumSTATSTGImpl_Construct(
    This->ancestorStorage,
    This->rootPropertySetIndex);

  /*
   * Search the enumeration for the property with the given name
   */
  foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(
    propertyEnumeration,
    pwcsName,
    &currentProperty);

  /*
   * Delete the property enumeration since we don't need it anymore
   */
  IEnumSTATSTGImpl_Destroy(propertyEnumeration);

  /*
   * If it was found, construct the stream object and return a pointer to it.
   */
  if ( (foundPropertyIndex!=PROPERTY_NULL) &&
       (currentProperty.propertyType==PROPTYPE_STREAM) )
  {
    newStream = StgStreamImpl_Construct(This, grfMode, foundPropertyIndex);

    if (newStream!=0)
    {
      newStream->grfMode = grfMode;
      *ppstm = (IStream*)newStream;

      /*
       * Since we are returning a pointer to the interface, we have to
       * nail down the reference.
       */
      IStream_AddRef(*ppstm);

      res = S_OK;
      goto end;
    }

    res = E_OUTOFMEMORY;
    goto end;
  }

  res = STG_E_FILENOTFOUND;

end:
  if (res == S_OK)
    TRACE("<-- IStream %p\n", *ppstm);
  TRACE("<-- %08x\n", res);
  return res;
}

/************************************************************************
 * Storage32BaseImpl_OpenStorage (IStorage)
 *
 * This method will open a new storage object from the current storage.
 *
 * See Windows documentation for more details on IStorage methods.
 */
static HRESULT WINAPI StorageBaseImpl_OpenStorage(
  IStorage*        iface,
  const OLECHAR*   pwcsName,      /* [string][unique][in] */
  IStorage*        pstgPriority,  /* [unique][in] */
  DWORD            grfMode,       /* [in] */
  SNB              snbExclude,    /* [unique][in] */
  DWORD            reserved,      /* [in] */
  IStorage**       ppstg)         /* [out] */
{
  StorageBaseImpl *This = (StorageBaseImpl *)iface;
  StorageInternalImpl* newStorage;
  IEnumSTATSTGImpl*      propertyEnumeration;
  StgProperty            currentProperty;
  ULONG                  foundPropertyIndex;
  HRESULT                res = STG_E_UNKNOWN;

  TRACE("(%p, %s, %p, %x, %p, %d, %p)\n",
	iface, debugstr_w(pwcsName), pstgPriority,
	grfMode, snbExclude, reserved, ppstg);

  /*
   * Perform a sanity check on the parameters.
   */
  if ( (This==0) || (pwcsName==NULL) || (ppstg==0) )
  {
    res = E_INVALIDARG;
    goto end;
  }

  /* as documented */
  if (snbExclude != NULL)
  {
    res = STG_E_INVALIDPARAMETER;
    goto end;
  }

  /*
   * Validate the STGM flags
   */
  if ( FAILED( validateSTGM(grfMode) ))
  {
    res = STG_E_INVALIDFLAG;
    goto end;
  }

  /*
   * As documented.
   */
  if ( STGM_SHARE_MODE(grfMode) != STGM_SHARE_EXCLUSIVE ||
        (grfMode & STGM_DELETEONRELEASE) ||
        (grfMode & STGM_PRIORITY) )
  {
    res = STG_E_INVALIDFUNCTION;
    goto end;
  }

  /*
   * Check that we're compatible with the parent's storage mode,
   * but only if we are not transacted
   */
  if(!(This->ancestorStorage->base.openFlags & STGM_TRANSACTED)) {
    if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( This->openFlags ) )
    {
      res = STG_E_ACCESSDENIED;
      goto end;
    }
  }

  /*
   * Initialize the out parameter
   */
  *ppstg = NULL;

  /*
   * Create a property enumeration to search the properties
   */
  propertyEnumeration = IEnumSTATSTGImpl_Construct(
                          This->ancestorStorage,
                          This->rootPropertySetIndex);

  /*
   * Search the enumeration for the property with the given name
   */
  foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(
                         propertyEnumeration,
                         pwcsName,
                         &currentProperty);

  /*
   * Delete the property enumeration since we don't need it anymore
   */
  IEnumSTATSTGImpl_Destroy(propertyEnumeration);

  /*
   * If it was found, construct the stream object and return a pointer to it.
   */
  if ( (foundPropertyIndex!=PROPERTY_NULL) &&
       (currentProperty.propertyType==PROPTYPE_STORAGE) )
  {
    /*
     * Construct a new Storage object
     */
    newStorage = StorageInternalImpl_Construct(
                   This->ancestorStorage,
                   grfMode,
                   foundPropertyIndex);

    if (newStorage != 0)
    {
      *ppstg = (IStorage*)newStorage;

      /*
       * Since we are returning a pointer to the interface,
       * we have to nail down the reference.
       */
      StorageBaseImpl_AddRef(*ppstg);

      res = S_OK;
      goto end;
    }

    res = STG_E_INSUFFICIENTMEMORY;
    goto end;
  }

  res = STG_E_FILENOTFOUND;

end:
  TRACE("<-- %08x\n", res);
  return res;
}

/************************************************************************
 * Storage32BaseImpl_EnumElements (IStorage)
 *
 * This method will create an enumerator object that can be used to
 * retrieve informatino about all the properties in the storage object.
 *
 * See Windows documentation for more details on IStorage methods.
 */
static HRESULT WINAPI StorageBaseImpl_EnumElements(
  IStorage*       iface,
  DWORD           reserved1, /* [in] */
  void*           reserved2, /* [size_is][unique][in] */
  DWORD           reserved3, /* [in] */
  IEnumSTATSTG**  ppenum)    /* [out] */
{
  StorageBaseImpl *This = (StorageBaseImpl *)iface;
  IEnumSTATSTGImpl* newEnum;

  TRACE("(%p, %d, %p, %d, %p)\n",
	iface, reserved1, reserved2, reserved3, ppenum);

  /*
   * Perform a sanity check on the parameters.
   */
  if ( (This==0) || (ppenum==0))
    return E_INVALIDARG;

  /*
   * Construct the enumerator.
   */
  newEnum = IEnumSTATSTGImpl_Construct(
              This->ancestorStorage,
              This->rootPropertySetIndex);

  if (newEnum!=0)
  {
    *ppenum = (IEnumSTATSTG*)newEnum;

    /*
     * Don't forget to nail down a reference to the new object before
     * returning it.
     */
    IEnumSTATSTG_AddRef(*ppenum);

    return S_OK;
  }

  return E_OUTOFMEMORY;
}

/************************************************************************
 * Storage32BaseImpl_Stat (IStorage)
 *
 * This method will retrieve information about this storage object.
 *
 * See Windows documentation for more details on IStorage methods.
 */
static HRESULT WINAPI StorageBaseImpl_Stat(
  IStorage*        iface,
  STATSTG*         pstatstg,     /* [out] */
  DWORD            grfStatFlag)  /* [in] */
{
  StorageBaseImpl *This = (StorageBaseImpl *)iface;
  StgProperty    curProperty;
  BOOL           readSuccessful;
  HRESULT        res = STG_E_UNKNOWN;

  TRACE("(%p, %p, %x)\n",
	iface, pstatstg, grfStatFlag);

  /*
   * Perform a sanity check on the parameters.
   */
  if ( (This==0) || (pstatstg==0))
  {
    res = E_INVALIDARG;
    goto end;
  }

  /*
   * Read the information from the property.
   */
  readSuccessful = StorageImpl_ReadProperty(
                    This->ancestorStorage,
                    This->rootPropertySetIndex,
                    &curProperty);

  if (readSuccessful)
  {
    StorageUtl_CopyPropertyToSTATSTG(
      pstatstg,
      &curProperty,
      grfStatFlag);

    pstatstg->grfMode = This->openFlags;
    pstatstg->grfStateBits = This->stateBits;

    res = S_OK;
    goto end;
  }

  res = E_FAIL;

end:
  if (res == S_OK)
  {
    TRACE("<-- STATSTG: pwcsName: %s, type: %d, cbSize.Low/High: %d/%d, grfMode: %08x, grfLocksSupported: %d, grfStateBits: %08x\n", debugstr_w(pstatstg->pwcsName), pstatstg->type, pstatstg->cbSize.u.LowPart, pstatstg->cbSize.u.HighPart, pstatstg->grfMode, pstatstg->grfLocksSupported, pstatstg->grfStateBits);
  }
  TRACE("<-- %08x\n", res);
  return res;
}

/************************************************************************
 * Storage32BaseImpl_RenameElement (IStorage)
 *
 * This method will rename the specified element.
 *
 * See Windows documentation for more details on IStorage methods.
 *
 * Implementation notes: The method used to rename consists of creating a clone
 *    of the deleted StgProperty object setting it with the new name and to
 *    perform a DestroyElement of the old StgProperty.
 */
static HRESULT WINAPI StorageBaseImpl_RenameElement(
            IStorage*        iface,
            const OLECHAR*   pwcsOldName,  /* [in] */
            const OLECHAR*   pwcsNewName)  /* [in] */
{
  StorageBaseImpl *This = (StorageBaseImpl *)iface;
  IEnumSTATSTGImpl* propertyEnumeration;
  StgProperty       currentProperty;
  ULONG             foundPropertyIndex;

  TRACE("(%p, %s, %s)\n",
	iface, debugstr_w(pwcsOldName), debugstr_w(pwcsNewName));

  /*
   * Create a property enumeration to search the properties
   */
  propertyEnumeration = IEnumSTATSTGImpl_Construct(This->ancestorStorage,
                                                   This->rootPropertySetIndex);

  /*
   * Search the enumeration for the new property name
   */
  foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(propertyEnumeration,
                                                     pwcsNewName,
                                                     &currentProperty);

  if (foundPropertyIndex != PROPERTY_NULL)
  {
    /*
     * There is already a property with the new name
     */
    IEnumSTATSTGImpl_Destroy(propertyEnumeration);
    return STG_E_FILEALREADYEXISTS;
  }

  IEnumSTATSTG_Reset((IEnumSTATSTG*)propertyEnumeration);

  /*
   * Search the enumeration for the old property name
   */
  foundPropertyIndex = IEnumSTATSTGImpl_FindProperty(propertyEnumeration,
                                                     pwcsOldName,
                                                     &currentProperty);

  /*
   * Delete the property enumeration since we don't need it anymore
   */
  IEnumSTATSTGImpl_Destroy(propertyEnumeration);

  if (foundPropertyIndex != PROPERTY_NULL)
  {
    StgProperty renamedProperty;
    ULONG       renamedPropertyIndex;

    /*
     * Setup a new property for the renamed property
     */
    renamedProperty.sizeOfNameString =
      ( lstrlenW(pwcsNewName)+1 ) * sizeof(WCHAR);

    if (renamedProperty.sizeOfNameString > PROPERTY_NAME_BUFFER_LEN)
      return STG_E_INVALIDNAME;

    strcpyW(renamedProperty.name, pwcsNewName);

    renamedProperty.propertyType  = currentProperty.propertyType;
    renamedProperty.startingBlock = currentProperty.startingBlock;
    renamedProperty.size.u.LowPart  = currentProperty.size.u.LowPart;
    renamedProperty.size.u.HighPart = currentProperty.size.u.HighPart;

    renamedProperty.previousProperty = PROPERTY_NULL;
    renamedProperty.nextProperty     = PROPERTY_NULL;

    /*
     * Bring the dirProperty link in case it is a storage and in which
     * case the renamed storage elements don't require to be reorganized.
     */
    renamedProperty.dirProperty = currentProperty.dirProperty;

    /* call CoFileTime to get the current time
    renamedProperty.timeStampS1
    renamedProperty.timeStampD1
    renamedProperty.timeStampS2
    renamedProperty.timeStampD2
    renamedProperty.propertyUniqueID
    */

    /*
     * Obtain a free property in the property chain
     */
    renamedPropertyIndex = getFreeProperty(This->ancestorStorage);

    /*
     * Save the new property into the new property spot
     */
    StorageImpl_WriteProperty(
      This->ancestorStorage,
      renamedPropertyIndex,
      &renamedProperty);

    /*
     * Find a spot in the property chain for our newly created property.
     */
    updatePropertyChain(
      (StorageImpl*)This,
      renamedPropertyIndex,
      renamedProperty);

    /*
     * At this point the renamed property has been inserted in the tree,
     * now, before Destroying the old property we must zero its dirProperty
     * otherwise the DestroyProperty below will zap it all and we do not want
     * this to happen.
     * Also, we fake that the old property is a storage so the DestroyProperty
     * will not do a SetSize(0) on the stream data.
     *
     * This means that we need to tweak the StgProperty if it is a stream or a
     * non empty storage.
     */
    StorageImpl_ReadProperty(This->ancestorStorage,
                             foundPropertyIndex,
                             &currentProperty);

    currentProperty.dirProperty  = PROPERTY_NULL;
    currentProperty.propertyType = PROPTYPE_STORAGE;
    StorageImpl_WriteProperty(
      This->ancestorStorage,
      foundPropertyIndex,
      &currentProperty);

    /*
     * Invoke Destroy to get rid of the ole property and automatically redo
     * the linking of its previous and next members...
     */
    IStorage_DestroyElement((IStorage*)This->ancestorStorage, pwcsOldName);

  }
  else
  {
    /*
     * There is no property with the old name
     */
    return STG_E_FILENOTFOUND;
  }

  return S_OK;
}

/************************************************************************
 * Storage32BaseImpl_CreateStream (IStorage)
 *

⌨️ 快捷键说明

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