Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
Home
Discussion GroupsVB SyntaxEnterprise DevelopmentDatabase AccessControlsCOMWin APICrystal ReportDeploymentGeneralGeneral 2
Related Topics
VB.NET / ASP.NETMS SQL ServerMS AccessOther Database ProductsMore Topics ...

VB Forum / Win API / September 2008



Tip: Looking for answers? Try searching our database.

SetFileInformationByHandle He

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Mike - 03 Sep 2008 18:14 GMT
I'm writing a filecopier using APIs.  I've gotten everything working, but I
want to set the destination file's date stamps match the source file's.  I
can get the info using GetFileInformationByHandle, but I'm stumped on the
SetFileInformationByHandle.  I'm using the Unicode versions because we often
encounter very long paths here.  Here's the MSDN page:
http://msdn.microsoft.com/en-us/library/aa365539(VS.85).aspx

(..Declarations)
Private Declare Function SetFileInformationByHanlde Lib "kernel32" ( _
   hFile As Long, FileInformationClass As FILE_INFO_BY_HANDLE_CLASS, _
   lpFileInformation As Long, dwBufferSize As Long) As Long

Private Declare Function GetFileInformationByHandle Lib "kernel32" ( _
    ByVal hFile As Long, lpFileInformation As BY_HANDLE_FILE_INFORMATION)
As Long

Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileW"
(ByVal lpFileName As Long, ByVal dwDesiredAccess As Long, ByVal dwShareMode
As Long, ByVal lpSecurityAttributes As Long, ByVal dwCreationDisposition As
Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As
Long

Private Type BY_HANDLE_FILE_INFORMATION
       dwFileAttributes As Long
       ftCreationTime As FILETIME
       ftLastAccessTime As FILETIME
       ftLastWriteTime As FILETIME
       dwVolumeSerialNumber As Long
       nFileSizeHigh As Long
       nFileSizeLow As Long
       nNumberOfLinks As Long
       nFileIndexHigh As Long
       nFileIndexLow As Long
End Type

Private Type FILE_BASIC_INFO
   CreationTime As Long
   LastAccessTime As Long
   LastWriteTime As Long
   ChangeTime As Long
   FileAttributes As String
End Type

Private Enum FILE_INFO_BY_HANDLE_CLASS
   FileBasicInfo
   FileStandardInfo
   FileNameInfo
   FileRenameInfo
   FileDispositionInfo
   FileAllocationInfo
   FileEndOfFileInfo
   FileStreamInfo
   FileCompressionInfo
   FileAttributeTagInfo
   FileIdBothDirectoryInfo
   FileIdBothDirectoryRestartInfo
   FileIoPriorityHintInfo
   MaximumFileInfoByHandlesClass
End Enum

Private Const GENERIC_WRITE = &H40000000
Private Const OPEN_EXISTING = 3

(Code)
   Dim srcHand as Long, destHand as Long, lngCopy as Long, lngSetInfo as
Long
   dim srcHFI As BY_HANDLE_FILE_INFORMATION
   If InStr(srcPath, "\\") = 1 Then                           'Prepends
"\\?\" to alert the API to use UNICODE names
       srcPath= "\\?\UNC\" & Mid$(srcPath, 3)
   Else
       srcPath= "\\?\" & srcPath
   End If
   If InStr(destPath, "\\") = 1 Then                           'Prepends
"\\?\" to alert the API to use UNICODE names
       destPath= "\\?\UNC\" & Mid$(destPath, 3)
   Else
       destPath= "\\?\" & destPath
   End If
   srcHand = CreateFile(StrPtr(srcPath), GENERIC_READ, 0, ByVal 0&,
OPEN_EXISTING, 0, 0)     ' get the handle of the source file
   srcHand = GetFileInformationByHandle(srcHand, srcHFI)
' get the File's info
   lngCopy  = CopyFile(StrPtr(srcPath), StrPtr(destPath), nFailFlag)
   destHand = CreateFile(StrPtr(destPath), GENERIC_READ, 0, ByVal 0&,
OPEN_EXISTING, 0, 0)
   lngSetInfo = SetFileInformationByHandle(destHand,FileBasicInfo, srcHFI,
len(srcHFI))                                                         '
<-THIS IS WHERE I GET STUCK! The third parameter is Long, but
                                                                           
                                                                           
                                        ' how to pass?  Am I even passing
the right object?  TIA!!
Stuart McCall - 03 Sep 2008 20:12 GMT
> I'm writing a filecopier using APIs.  I've gotten everything working, but
> I want to set the destination file's date stamps match the source file's.
[quoted text clipped - 87 lines]
>
> ' how to pass?  Am I even passing the right object?  TIA!!

You're going to kick yourself. You have a typo in the first declaration
(which also just happens to be the function you're having trouble with).

SetFileInformationByHanlde

should be:

SetFileInformationByHandle
Thorsten Albers - 03 Sep 2008 20:33 GMT
Mike <nospam@whitehouse.gov> schrieb im Beitrag
<ugHf$heDJHA.232@TK2MSFTNGP04.phx.gbl>...
> Private Declare Function SetFileInformationByHanlde Lib "kernel32" ( _
>     hFile As Long, FileInformationClass As FILE_INFO_BY_HANDLE_CLASS, _
>     lpFileInformation As Long, dwBufferSize As Long) As Long

- 'hFile As Long' has to be 'ByVal hFile As Long'
- 'dwBufferSize As Long' has to be 'ByVal dwBufferSize As Long'
- In order to be able to pass different structure types to this procedure
a) add one declare statement for every type or b) use 'lpFileInformation As
Any'.

a)
Private Declare Function SetFileInformationByHandleBasic _
                        Lib "kernel32" _
                        Alias "SetFileInformationByHandle"
                        ( _
                          ByVal hFile As Long, _
                          FileInformationClass As
FILE_INFO_BY_HANDLE_CLASS, _
                          lpFileInformation As FILE_BASIC_INFO, _
                          ByVal dwBufferSize As Long _
                        ) As Long

b)
Private Declare Function SetFileInformationByHandleBasic _
                        Lib "kernel32" _
                        Alias "SetFileInformationByHandle"
                        ( _
                          ByVal hFile As Long, _
                          FileInformationClass As
FILE_INFO_BY_HANDLE_CLASS, _
                          lpFileInformation As Any, _
                          ByVal dwBufferSize As Long _
                        ) As Long

> Private Type FILE_BASIC_INFO
>     CreationTime As Long
[quoted text clipped - 3 lines]
>     FileAttributes As String
> End Type

- 'FileAttributes As String' has to be 'FileAttributes As Long'
- All other structure members have to be '... As LARGE_INTEGER'

Private Type LARGE_INTEGER
 lowpart As Long
 highpart As Long
End Type

>     srcHand = CreateFile(StrPtr(srcPath), GENERIC_READ, 0, ByVal 0&,
> OPEN_EXISTING, 0, 0)
>     srcHand = GetFileInformationByHandle(srcHand, srcHFI)

- Don't overwrite the contents of 'srcHand' because you need the handle
later to close the file by a call to CloseHandle()
- The return value of GetFileInformationByHandle() is 0 (failure) or <> 0
(success)

>     lngCopy  = CopyFile(StrPtr(srcPath), StrPtr(destPath), nFailFlag)

- Remember, that as the third parameter you have to pass either 1 (TRUE) or
0 (FALSE)
- The return value of CopyFile() is 0 (failure) or <> 0 (success)

>     destHand = CreateFile(StrPtr(destPath), GENERIC_READ, 0, ByVal 0&,
> OPEN_EXISTING, 0, 0)

If you want to manipulate a file somehow you need GENERIC_WRITE access.

>     lngSetInfo = SetFileInformationByHandle(destHand,FileBasicInfo, srcHFI,
> len(srcHFI))                                                         '

- You can't pass 'srcHFI' to SetFileInformationByHandle(); if you want to
pass FILE_BASIC_INFO structure data to this procedure, you have to set the
data of that structure from the data of the 'srcHFI' structure and pass it
to the procedure.
- You have to close any handle retrieved from a call to CreateFile() by a
call to CloseHandle()!
- Be aware of the fact that SetFileInformationByHandle() is currently
available only on Windows Vista and Windows Server 2003.

You should read the MSDN documentation on each of the procedures again -
and carefully!

Signature

----------------------------------------------------------------------
Thorsten Albers                               albers(a)uni-freiburg.de
----------------------------------------------------------------------

expvb - 03 Sep 2008 21:36 GMT
> I'm writing a filecopier using APIs.  I've gotten everything working, but
> I want to set the destination file's date stamps match the source file's.
> I can get the info using GetFileInformationByHandle, but I'm stumped on
> the SetFileInformationByHandle.  I'm using the Unicode versions because we
> often encounter very long paths here.  Here's the MSDN page:
> http://msdn.microsoft.com/en-us/library/aa365539(VS.85).aspx

That function requires Vista+, you can use it on XP/2003 if you install some
DLL, but why not use GetFileTime/SetFileTime? They run on Windows 95+. Also,
you can use CopyFileW to copy files with long file names on NT, instead of
making your own. Example:

Option Explicit

Private Declare Function CopyFileW Lib "kernel32" ( _
   ByVal lpExistingFileName As Long, ByVal lpNewFileName As Long, _
   ByVal bFailIfExists As Long) As Long

Private Sub Form_Load()
   Dim fn1 As String
   Dim fn2 As String

   ' Set fn1 and fn2 here

   Debug.Print "CopyFileW returned " & CopyFileW(ByVal StrPtr(fn1), _
       ByVal StrPtr(fn2), 0)
End Sub
Karl E. Peterson - 03 Sep 2008 23:03 GMT
>> http://msdn.microsoft.com/en-us/library/aa365539(VS.85).aspx
>
> That function requires Vista+, you can use it on XP/2003 if you install some
> DLL, but why not use GetFileTime/SetFileTime? They run on Windows 95+.

Agreed!

> you can use CopyFileW to copy files with long file names on NT, instead of
> making your own.

Main reason I'd suggest would be to track the progress.
Signature

.NET: It's About Trust!
http://vfred.mvps.org

expvb - 03 Sep 2008 23:09 GMT
>>> http://msdn.microsoft.com/en-us/library/aa365539(VS.85).aspx
>>
[quoted text clipped - 9 lines]
>
> Main reason I'd suggest would be to track the progress.

CopyFileExW can do that, but it requires Windows 98+.
Karl E. Peterson - 03 Sep 2008 23:43 GMT
>>> you can use CopyFileW to copy files with long file names on NT, instead
>>> of making your own.
>>
>> Main reason I'd suggest would be to track the progress.
>
> CopyFileExW can do that, but it requires Windows 98+.

Seems to not be a totally unreasonable requirement anymore. <g>
Signature

.NET: It's About Trust!
http://vfred.mvps.org

Thorsten Albers - 04 Sep 2008 04:25 GMT
expvb <nobody@cox.net> schrieb im Beitrag
<OAh4NHhDJHA.5316@TK2MSFTNGP04.phx.gbl>...
> CopyFileExW can do that, but it requires Windows 98+.

In fact in requires Windows NT >= 3.51 - because on Windows 9x the "W"
versions of these procedures aren't available (as well as the special file
path parsing with "\\?\"). CopyFileExA() works on Windows 98/ME.

Signature

----------------------------------------------------------------------
Thorsten Albers                               albers(a)uni-freiburg.de
----------------------------------------------------------------------

 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.