PDA

View Full Version : Addition to vWin32fh



Michael Mullan
9-Jun-2009, 10:11 AM
I needed a function to create multiple levels of directories in one step

as in
md c:\exports\2009\july\4th\ rather than

MD C:\exports
md c:\exports\2009
md c:\exports\2009\july
md c:\exports\2009\july\4thso I added Micro$ofts shCreateDirectoryEX function to vWin32fh

in vWin32fh.h at the bottom of the file I Added..

// Michael Mullan. I Wanted to create all the folders in one statement...

// SHCreateDirectoryEx

// Note This function is available through Microsoft Windows XP Service Pack 2 (SP2) and Windows Server 2003.
// It might be altered or unavailable in subsequent versions of Windows.
//
// This function creates a file system folder whose fully qualified path is given by pszPath. If one or more
// of the intermediate folders do not exist, they are created as well. SHCreateDirectoryEx also verifies that
// the files are visible. If they are not visible, expect one of the following:
//
// * If hwnd is set to a valid window handle, a message box is displayed warning the user that he or she
// might not be able to access the files. If the user chooses not to proceed, the function returns
// ERROR_CANCELLED.
// * If hwnd is set to NULL, no user interface is displayed and the function returns ERROR_CANCELLED.

// Returns ERROR_SUCCESS if successful. If the operation fails, other error codes can be returned,
// including those listed here. For values not specifically listed, see System Error Codes.
// 161 ERROR_BAD_PATHNAME The pszPath parameter was set to a relative path.
// 206 ERROR_FILENAME_EXCED_RANGE The path pointed to by pszPath is too long.
// 3 ERROR_PATH_NOT_FOUND The system cannot find the path pointed to by pszPath. The path may contain an invalid entry.
// 80 ERROR_FILE_EXISTS The directory exists.
// 183 ERROR_ALREADY_EXISTS The directory exists.
// 1223 ERROR_CANCELLED The user canceled the operation.

// int SHCreateDirectoryEx(
// HWND hwnd,
// LPCTSTR pszPath,
// const SECURITY_ATTRIBUTES *psa
// );

External_function vWin32_SHCreateDirectoryEx "SHCreateDirectoryExA" shell32.dll Handle hWnd;
pointer pszPath Pointer lpSecurity_Attributes Returns Integer and to vWin32fh.pkg I added
// Create the folder, including intermediate directories.
// Don't panic if the folder already exists.
// Michael Mullan June 2009.
Function vshCreateDirectoryEX Global String sNewFolder Returns Integer
String sFolder sSA
Pointer lpsFolder lpsSecurity_Attributes lpDescriptor
Integer iRetval bFolderCreated bInheritHandle

Move (False) to bFolderCreated
// fill string variable with null characters
ZeroType vtSecurity_attributes to sSA

// null MAX_PATH chars into var (make space)
Move (Repeat(Character(0), vMAX_PATH)) to sFolder

If (sNewFolder <> "") Begin

Move dfTrue to bInheritHandle
// Setting this to NULL is already done by the zerotype command
// Move NULL To lpDescriptor
Put (length(sSA)) to sSA At vtSecurity_attributes.nLength
//Put lpDescriptor To sSA at vtSecurity_attributes.lpDescriptor
Put bInheritHandle to sSA At vtSecurity_attributes.bInheritHandle

GetAddress of sSA to lpsSecurity_Attributes

//
Move sNewFolder to sFolder
GetAddress of sFolder to lpsFolder
Move (vWin32_SHCreateDirectoryEx(0,lpsFolder, lpsSecurity_Attributes)) to bFolderCreated
End

If (bFolderCreated <> 0) Begin
Move 1 to iRetVal
String sErr

If (bFolderCreated = 161 ) Send UserError ("Path " + sNewFolder + " is Not Valid") "ERROR_BAD_PATHNAME"
Else If (bFolderCreated = 206 ) Send UserError ("Path " + sNewFolder + " is Not Valid") "ERROR_FILENAME_EXCED_RANGE "
Else If (bFolderCreated = 3 ) Send UserError ("Path " + sNewFolder + " is Not Valid") "ERROR_PATH_NOT_FOUND"
Else If (bFolderCreated = 80 ) Move 0 to iRetval // "ERROR_FILE_EXISTS" not really an error
Else If (bFolderCreated = 183 ) Move 0 to iRetval // "ERROR_ALREADY_EXISTS" not really an error
Else If (bFolderCreated = 1223) Send UserError ("Path " + sNewFolder + " is Not Valid") "ERROR_CANCELLED"
Else Send UserError ("Folder Createion Error # " + String(bfoldercreated) + "\n" + sNewFolder) "FILE_CREATION_ERROR"
End
Function_Return iRetVal
End_Function // vCreateDirectory

Ola Eldoy
10-Jun-2009, 06:26 AM
That's great, Michael!

BTW, is vWin32fh currently being maintained in a source control repository at VDF-Guidance?

Michael Mullan
10-Jun-2009, 06:28 AM
I believe so, but I'm really busy right now, and don't really have time to figure out how to get check in rights, and actually check it in.

MM.

Ola Eldoy
15-Jun-2009, 07:39 AM
Suddenly, I find myself needing this function. How odd is that?

BTW, the variables lpDescriptor and sErr are not used, and their definitions can thus safely be removed. The procedure UserError also needs to be defined somewhere. Perhaps I am missing something here? In any case, Michael, I am taking the liberty of reposting this adjusted version of your vshCreateDirectoryEX function.

Thanks for the nice work!



// Create the folder, including intermediate directories.
// Don't panic if the folder already exists.
// Michael Mullan June 2009.
Function vshCreateDirectoryEX Global String sNewFolder Returns Integer
String sFolder sSA
Pointer lpsFolder lpsSecurity_Attributes
Integer iRetval bFolderCreated bInheritHandle
Move (False) to bFolderCreated
// fill string variable with null characters
ZeroType vtSecurity_attributes to sSA
// null MAX_PATH chars into var (make space)
Move (Repeat(Character(0), vMAX_PATH)) to sFolder
If (sNewFolder <> "") Begin
Move dfTrue to bInheritHandle
// Setting this to NULL is already done by the zerotype command
// Move NULL To lpDescriptor
Put (length(sSA)) to sSA At vtSecurity_attributes.nLength
//Put lpDescriptor To sSA at vtSecurity_attributes.lpDescriptor
Put bInheritHandle to sSA At vtSecurity_attributes.bInheritHandle
GetAddress of sSA to lpsSecurity_Attributes
//
Move sNewFolder to sFolder
GetAddress of sFolder to lpsFolder
Move (vWin32_SHCreateDirectoryEx(0,lpsFolder, lpsSecurity_Attributes)) to bFolderCreated
End

If (bFolderCreated <> 0) Begin
Move 1 to iRetVal

If (bFolderCreated = 161 ) Error DFERR_OPERATOR ("Path " + sNewFolder + " is Not Valid (ERROR_BAD_PATHNAME)")
Else If (bFolderCreated = 206 ) Error DFERR_OPERATOR ("Path " + sNewFolder + " is Not Valid (ERROR_FILENAME_EXCED_RANGE)")
Else If (bFolderCreated = 3 ) Error DFERR_OPERATOR ("Path " + sNewFolder + " is Not Valid (ERROR_PATH_NOT_FOUND)")
Else If (bFolderCreated = 80 ) Move 0 to iRetval // "ERROR_FILE_EXISTS" not really an error
Else If (bFolderCreated = 183 ) Move 0 to iRetval // "ERROR_ALREADY_EXISTS" not really an error
Else If (bFolderCreated = 1223) Error DFERR_OPERATOR ("Path " + sNewFolder + " is Not Valid (ERROR_CANCELLED)")
Else Error DFERR_OPERATOR ("Folder Creation Error # " + String(bfoldercreated) + "\n" + sNewFolder + "(FILE_CREATION_ERROR)")
End
Function_Return iRetVal
End_Function // vshCreateDirectoryEX

Michael Mullan
15-Jun-2009, 08:23 AM
UserError is one of the cool new bits built in to vdf 14.1

Iirc

Ola Eldoy
15-Jun-2009, 09:14 AM
Oops. Still haven't migrated from 14.0...

wila
17-Jun-2009, 11:08 AM
That's great, Michael!

BTW, is vWin32fh currently being maintained in a source control repository at VDF-Guidance?
:rolleyes: Umm... no it is not. Well not as a separate entity at least.

I will see that it will be before the end of the week and add the new code in there as well.
Will add a link here when it is done.
Drop me a note if you want commit access.

--
Wil

wila
4-Oct-2009, 10:19 AM
I will see that it will be before the end of the week and add the new code in there as well.


Humm, my sense of time is a bit off I think, or I just forgot about it.
Just created the subversion project and added the suggested code, along with a few other minor changes, see the project page for the URL.
http://www.vdf-guidance.com/ContribPage.asp?Page=PKGWINAPIVWIN32F&ContribRecId=80

These changes are only available via subversion at the moment as I'm rather conservative before I release changes to most of my code.
--
Wil