SHFILEOPSTRUCT and the SHFileOperation

Environment: Windows 9x/NT/2K, Version 4.00 (or later) of Shell32.dll

Introduction

The function SHFileOperation, enables you to copy, move or delete a file system object. As you can see, this function takes as its sole parameter a pointer to a SHFILEOPSTRUCT structure (also shown below).

// SHFileOperation syntax
WINSHELLAPI int WINAPI SHFileOperation(LPSHFILEOPSTRUCT lpFileOp);

// SHFILEOPSTRUCT layout
typedef struct _SHFILEOPSTRUCT{
 HWND		hwnd;
 UINT		wFunc;
 LPCSTR		pFrom;
 LPCSTR		pTo;
 FILEOP_FLAGS	fFlags;
 BOOL		fAnyOperationsAborted;
 LPVOID		hNameMappings;
 LPCSTR		lpszProgressTitle;
} SHFILEOPSTRUCT, FAR *LPSHFILEOPSTRUCT;
Unfortunately, despite this function's obvious usefulness, the Microsoft documentation is very ambiguous regarding the SHFILEOPSTRUCT structure and how to fill it out. In fact, there are several pitfalls when using this structure. Therefore, in this article, I'll attempt to address these issues so that those of you using this function for the first time can benefit from my experience as to how to take advantage of this very handy function.

Name Collision Resolution and the hNameMappings member

hNameMappings is (almost always) an input-only member of SHFILEOPSTRUCT In fact, after the call to SHFileOperation has returned successfully, this value will be actually be set to NULL. The only time that this value will be changed by the SHFileOperation function is if you have specified the flags FOF_RENAMEONCOLLISION | FOF_WANTMAPPINGSHANDLE in the FILEOP_FLAGS member. Then if there were files that had to be renamed due to a name collision, assign a name mapping object will containing their old and new names to the hNameMappings member.

This member can be treated as a void pointer to a continuous memory block. This memory block in turn can be treated as some kind of the structure with int as a first member. Value of this integer indicates how many SHNAMEMAPPING structures follows. This way you can retrieve needed info.

File Name Retrieval

Another pitfall that you need to know about deals with retrieving the names of files. pszOldPath and pszNewPath members are declared as LPSTR. However, they are laid out as DWORD; not char! Therefore, any string copying function available fails to successfully copy the path strings.

Sample Code

Here is a code snippet illustrating these issues. It can be done differently and is not posted for the purpose of code review. Treat it rather as a suggestion.
CString OldPath;
CString NewPath;
SHFILEOPSTRUCT shFileOp;

//after filling other members:
shFileOp.fFlags = FOF_WANTMAPPINGHANDLE 
                | FOF_RENAMEONCOLLISION;

shFileOp.lpszProgressTitle = "Test";
shFileOp.fAnyOperationsAborted = FALSE;

SHFileOperation(&shFileOp);

if(!shFileOp.hNameMappings) 
 return;	//there is nothing further to do, no file collision

struct TMPMAP
{
int Indx;
SHNAMEMAPPING *pMapping;
};

//this will give you a  pointer to the beginning of the 
//array of SHNAMEMAPPING structures
TMPMAP *pTmpMap = (TMPMAP*)shFileOp.hNameMappings;

for(int in = 0; in < pTmpMap->Indx; in++)
{
 SHNAMEMAPPING *pMap = &pTmpMap->pMapping[in];

 //do the same thing for csOldPath
 /*********************************************************/
 char *buf = csNewPath.GetBufferSetLength(pMap->cchNewPath);

strcpy(buf, (char*)pMap->pszOldPath); //see the result of
this,

for(int dw = 0 ; dw < 2 * pMap->cchNewPath - 1 ; dw+=2)
{
*buf = (pMap->pszNewPath[dw]);
buf++;
}
buf = 0;
csNewPath.ReleaseBuffer();  //and see the result of this.
/**********************************************************/
}

//always free it if requested
SHFreeNameMappings(shFileOp.hNameMappings); 


About the Author

John Z. Czopowik VC++ MVP

Microsoft VC++ MVP

Comments

  • how to use ShFileOperation in pb8.0

    Posted by xuweiqun1982 on 07/06/2004 09:57pm

    how to use ShFileOperation in pb8.0

    Reply
  • how to get files information in a directory?

    Posted by Legacy on 05/15/2003 12:00am

    Originally posted by: cixic

    help

    Reply
  • How copy security attributes in ShFileOperation ?

    Posted by Legacy on 09/24/2002 12:00am

    Originally posted by: Dmitry

    On W2K ShFileOperation do'nt copy ACL.
    Need FOF_* constant ?

    • How copy security attributes in ShFileOperation ?

      Posted by iatethewholething on 09/21/2006 04:15am

      I believe SHFileOperation only retains ACLs in a copy if the copy is cross volume (different drive) on the local machine. If it is the same volume - it is not retained. Same thing if you use CopyFile/CopyFileEx. You need to use a separate API to copy and apply the ACLs from the source to the destination.

      Reply
    Reply
  • Getting It Out Of The Recycling Bin

    Posted by Legacy on 06/08/2001 12:00am

    Originally posted by: swinefeaster

    I am writing an application that makes extensive
    
    use of an unlimited undo / redo mechanism, and I've also added the ability for my users to delete files off the hard drive through my gui. I am using the following code to delete a file and send it to the
    recycling bin:

    SHFILEOPSTRUCT OpInfo;
    OpInfo.hwnd = ::AfxGetMainWnd()->m_hWnd;
    OpInfo.wFunc = FO_DELETE;
    OpInfo.pFrom = FilenameStringRaw;
    OpInfo.pTo = NULL;

    OpInfo.fFlags = FOF_ALLOWUNDO | FOF_FILESONLY | FOF_NOCONFIRMATION |
    FOF_SILENT | FOF_NOERRORUI;

    int result = ::SHFileOperation(&OpInfo);

    MHogDeleteArray(&FilenameStringRaw);

    Now that all works fine. The problem is---how do I let the user UNDO the
    delete programmatically? The flag FOF_ALLOWUNDO suggests that this
    should be possible, but I can't figure out how. Been looking everywhere.

    Thanks.

    Matus

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: December 11, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Market pressures to move more quickly and develop innovative applications are forcing organizations to rethink how they develop and release applications. The combination of public clouds and physical back-end infrastructures are a means to get applications out faster. However, these hybrid solutions complicate DevOps adoption, with application delivery pipelines that span across complex hybrid cloud and non-cloud environments. Check out this …

  • VMware vCloud® Government Service provided by Carpathia® is an enterprise-class hybrid cloud service that delivers the tried and tested VMware capabilities widely used by government organizations today, with the added security and compliance assurance of FedRAMP authorization. The hybrid cloud is becoming more and more prevalent – in fact, nearly three-fourths of large enterprises expect to have hybrid deployments by 2015, according to a recent Gartner analyst report. Learn about the benefits of …

Most Popular Programming Stories

More for Developers

RSS Feeds