CStreams 64bit?
-
- BronzeLounger
- Posts: 1272
- Joined: 03 Feb 2010, 19:59
- Location: Terneuzen, the Netherlands
CStreams 64bit?
I’ve been using CStreams code from Karl E. Peterson (https://classicvb.net/samples/Streams/) in Excel VBA.
I moved to MSO365 64-bit and I am getting errors in my code. I can fix some of these, but as I also use the CStreams Class module, I believe that one needs adoption for 64 bit as well.
Is that available somewhere maybe?
Any help would be very much appreciated!
I moved to MSO365 64-bit and I am getting errors in my code. I can fix some of these, but as I also use the CStreams Class module, I believe that one needs adoption for 64 bit as well.
Is that available somewhere maybe?
Any help would be very much appreciated!
-
- Administrator
- Posts: 78686
- Joined: 16 Jan 2010, 00:14
- Status: Microsoft MVP
- Location: Wageningen, The Netherlands
Re: CStreams 64bit?
You'll need to update the Declare lines in the (class) modules, and the code that calls Windows API functions.
See Office 2010 Help Files: Win32API_PtrSafe with 64-bit Support
See Office 2010 Help Files: Win32API_PtrSafe with 64-bit Support
Best wishes,
Hans
Hans
-
- BronzeLounger
- Posts: 1272
- Joined: 03 Feb 2010, 19:59
- Location: Terneuzen, the Netherlands
Re: CStreams 64bit?
Great thanks... I was able to adjust some, but I couldn't find these (maybe they are OK? Maybe I messed them up already?)
Private Declare PtrSafe Function NtQueryInformationFile Lib "ntdll" (ByVal FileHandle As Long, ByRef ioStatusBlock As IO_STATUS_BLOCK, FileInformation As Any, ByVal StructureLength As Long, ByVal FileInformationClass As FILE_INFORMATION_CLASS) As Long
Private Declare PtrSafe Function lstrlenW Lib "kernel32" (ByVal lpString As Long) As Long
Private Declare PtrSafe Function FindFirstFileW Lib "kernel32.dll" (ByVal lpFileName As String, ByRef lpFindFileData As WIN32_FIND_DATA) As LongPtr
Private Declare PtrSafe Function FindNextFileW Lib "kernel32.dll" (ByVal hFindFile As LongPtr, ByRef lpFindFileData As WIN32_FIND_DATA) As LongPtr
Private Declare PtrSafe Function NtQueryInformationFile Lib "ntdll" (ByVal FileHandle As Long, ByRef ioStatusBlock As IO_STATUS_BLOCK, FileInformation As Any, ByVal StructureLength As Long, ByVal FileInformationClass As FILE_INFORMATION_CLASS) As Long
Private Declare PtrSafe Function lstrlenW Lib "kernel32" (ByVal lpString As Long) As Long
Private Declare PtrSafe Function FindFirstFileW Lib "kernel32.dll" (ByVal lpFileName As String, ByRef lpFindFileData As WIN32_FIND_DATA) As LongPtr
Private Declare PtrSafe Function FindNextFileW Lib "kernel32.dll" (ByVal hFindFile As LongPtr, ByRef lpFindFileData As WIN32_FIND_DATA) As LongPtr
-
- 5StarLounger
- Posts: 818
- Joined: 24 Jan 2010, 15:56
Re: CStreams 64bit?
The first argument to NtQueryInformationFile is a handle so should be LongPtr too.
Regards,
Rory
Rory
-
- BronzeLounger
- Posts: 1272
- Joined: 03 Feb 2010, 19:59
- Location: Terneuzen, the Netherlands
Re: CStreams 64bit?
Thanks...This ain't easy. I now have this piece:
lpBlock is a LongPrt and I seem to now get an error on the code line above...
<Edit> This is that routine (and something is probably wrong now):
Code: Select all
PointerToLargeInteger(lpBlock + 8)
<Edit> This is that routine (and something is probably wrong now):
Code: Select all
Private Sub GetStreams(InfoBlock() As Byte)
Dim nIndex As Long
Dim lpBlock As LongPtr
' Reset count to zero, and walk through information block.
m_Count = 0
nIndex = LBound(InfoBlock)
Do
' Expand persisted storage for stream information
ReDim Preserve m_Streams(0 To m_Count) _
As FILE_STREAM_INFORMATION
With m_Streams(m_Count)
' Calculate pointer to beginning of this block.
lpBlock = VarPtr(InfoBlock(nIndex))
' Find offset to next record.
.NextEntryOffset = PointerToDWord(lpBlock)
' Read each of the remaining attributes for this stream.
.StreamNameLength = PointerToDWord(lpBlock + 4)
.StreamSize = PointerToLargeInteger(lpBlock + 8)
.StreamAllocationSize = PointerToLargeInteger(lpBlock + 16)
If .StreamNameLength Then
.StreamName = PointerToStringW(lpBlock + 24, .StreamNameLength)
End If
' Increment count of streams.
m_Count = m_Count + 1
' Bump up buffer pointer to next record.
If .NextEntryOffset Then
nIndex = nIndex + .NextEntryOffset
Else
Exit Do
End If
End With
Loop
End Sub
-
- BronzeLounger
- Posts: 1272
- Joined: 03 Feb 2010, 19:59
- Location: Terneuzen, the Netherlands
Re: CStreams 64bit?
I'm making slow progress. Now stuck here:
32 bit
Declares:
Code:
64 bit
Declares:
and
Code gives error in the "ByVal0&" part of the call. I get that as that changed from 0 to the SECURITY_ATTRIBUTES type. So what do I do here now?
32 bit
Declares:
Code: Select all
Private Declare Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As Any, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As Long) As Long
Code: Select all
hFile = CreateFile(m_FileName, 0&, FILE_SHARE_READ, ByVal 0&, OPEN_EXISTING, Flags, 0&)
Declares:
Code: Select all
Private Declare PtrSafe Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As SECURITY_ATTRIBUTES, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As LongPtr) As LongPtr
Code: Select all
Private Type SECURITY_ATTRIBUTES
nLength As Long
lpSecurityDescriptor As LongPtr
bInheritHandle As Long
End Type
-
- 5StarLounger
- Posts: 818
- Joined: 24 Jan 2010, 15:56
-
- BronzeLounger
- Posts: 1272
- Joined: 03 Feb 2010, 19:59
- Location: Terneuzen, the Netherlands
Re: CStreams 64bit?
Hans pointed me to a Microsoft file that gives guidance in converting API calls from 32 to 64 bit. That file is called: Win32API_PtrSafe.TXT
I used this file to convert the STREAMS code to 64 bit and for the CreateFile call that was the 64-bit suggested format.
I could try to put ANY back but I'm not sure what that would do.
I used this file to convert the STREAMS code to 64 bit and for the CreateFile call that was the 64-bit suggested format.
I could try to put ANY back but I'm not sure what that would do.
-
- 5StarLounger
- Posts: 818
- Joined: 24 Jan 2010, 15:56
Re: CStreams 64bit?
You could try simply removing the & from the end, since 64bit will be expecting a LongLong and & is the type character for Long (you'd need ^ for a LongLong).
Regards,
Rory
Rory
-
- BronzeLounger
- Posts: 1272
- Joined: 03 Feb 2010, 19:59
- Location: Terneuzen, the Netherlands
Re: CStreams 64bit?
"User-defined type may not be passed ByVal"
I think that makes sense as it's now expecting this user define type: SECURITY_ATTRIBUTES
Somehow I need to pass that and make it behave like the "0&" that was there in the 32 bit version
-
- BronzeLounger
- Posts: 1272
- Joined: 03 Feb 2010, 19:59
- Location: Terneuzen, the Netherlands
-
- 5StarLounger
- Posts: 818
- Joined: 24 Jan 2010, 15:56
-
- BronzeLounger
- Posts: 1272
- Joined: 03 Feb 2010, 19:59
- Location: Terneuzen, the Netherlands
Re: CStreams 64bit?
Long. And yes, still as 0& because changes still gave errors as I reported
-
- 5StarLounger
- Posts: 818
- Joined: 24 Jan 2010, 15:56
Re: CStreams 64bit?
hFile needs to be a LongPtr since your API declaration returns a LongPtr.
Regards,
Rory
Rory
-
- BronzeLounger
- Posts: 1272
- Joined: 03 Feb 2010, 19:59
- Location: Terneuzen, the Netherlands
Re: CStreams 64bit?
I made that adjustment, thank you.
But the error remains as a user type is still expected....
I'll also search myself for this call in 64 bit, see if I find something. Will post if I do
But the error remains as a user type is still expected....
I'll also search myself for this call in 64 bit, see if I find something. Will post if I do
-
- BronzeLounger
- Posts: 1272
- Joined: 03 Feb 2010, 19:59
- Location: Terneuzen, the Netherlands
Re: CStreams 64bit?
OK, some progress. I changed the declare as could (should)
be NULL most of the time:
So the call becomes:
No compile errors here anymore but a new series pops-up now.
Working on that and will update later
be NULL most of the time:
Code: Select all
Private Declare PtrSafe Function CreateFile Lib "kernel32" Alias "CreateFileA" (ByVal lpFileName As String, ByVal dwDesiredAccess As Long, ByVal dwShareMode As Long, lpSecurityAttributes As Any, ByVal dwCreationDisposition As Long, ByVal dwFlagsAndAttributes As Long, ByVal hTemplateFile As LongPtr) As LongPtr
Code: Select all
hFile = CreateFile(m_FileName, 0&, FILE_SHARE_READ, Null, OPEN_EXISTING, Flags, 0&)
Working on that and will update later
-
- BronzeLounger
- Posts: 1272
- Joined: 03 Feb 2010, 19:59
- Location: Terneuzen, the Netherlands
Re: CStreams 64bit?
Next problem is here...
The .LUID gives "Method or Datamember not found". I understand but don't know how to fix.
tkp is defined in this function: Dim tkp As TOKEN_PRIVILEGES
LookupPrivilegeValue is declared as
So I need to look at LUID in TOKEN_PRIVILEGES. It was there in 32-bit but 64-bit has this:
Therefore I need to find "LUID_AND_ATTRIBUTES", and it is there:
So how to I fix the call?
Note that this is the definition of LUID:
Code: Select all
If LookupPrivilegeValue(vbNullString, SE_BACKUP_NAME, tkp.LUID) Then
tkp is defined in this function: Dim tkp As TOKEN_PRIVILEGES
LookupPrivilegeValue is declared as
Code: Select all
Private Declare PtrSafe Function LookupPrivilegeValue Lib "advapi32" Alias "LookupPrivilegeValueA" (ByVal lpSystemName As String, ByVal lpName As String, lpLuid As LARGE_INTEGER) As Long
Code: Select all
Private Type TOKEN_PRIVILEGES
PrivilegeCount As Long
Privileges(ANYSIZE_ARRAY) As LUID_AND_ATTRIBUTES
End Type
Code: Select all
Private Type LUID_AND_ATTRIBUTES
pLuid As LUID
Attributes As Long
End Type
Note that this is the definition of LUID:
Code: Select all
Private Type LUID
LowPart As Long
HighPart As Long
End Type
-
- 5StarLounger
- Posts: 818
- Joined: 24 Jan 2010, 15:56
Re: CStreams 64bit?
The declaration means that the function is expecting a LARGE_INTEGER type, not a TOKEN_PRIVILEGES. How/where have you defined the type?
Regards,
Rory
Rory
-
- BronzeLounger
- Posts: 1272
- Joined: 03 Feb 2010, 19:59
- Location: Terneuzen, the Netherlands
Re: CStreams 64bit?
OK, I'm clearly not an expert here but when I look in the call, I see that there "tkp.LUID" is used. So that should indeed be LARGE_INTEGER.
The structure 'tkp' is defined as "TOKEN_PRIVILEGES".
The latter is defined with two variables: "PrivilegeCount As Long" and "Privileges(ANYSIZE_ARRAY) As LUID_AND_ATTRIBUTES"
"LUID_AND_ATTRIBUTES" defines two variables "pLuid As LUID" and "Attributes As Long"
"LUID" also defines two variables: "LowPart As Long" and "HighPart As Long"
Indeed, you are right, none of the 'lower' variables are of the LARGE_INTEGER type...
I guess that call is wrong then maybe? I mean, I shouldn't use "tkp.LUID" but something else (but that has to be LARGE_INTEGER)...
Sofar I think I was able to adjust variable-types to make everything 'fit' the 64-bit model, seems that this time however I should actually go change a call itself (and unless someone understands what's going on here, I think I'd need more background and understanding to do that).
Let's not lose my goal out of sight: I'd like to be able to read/write NTFS Alternate Data Streams via VBA code in MSO365 (64bit). I'm doing that now by trying to 'adapt' existing 32-bit code that I found on the Internet and used successfully before.
I'm not 'stuck' to that approach however... any other VBA code that works for 64-bit Office will be more than fine as well (but I searched and couldn't find anything yet)...
The structure 'tkp' is defined as "TOKEN_PRIVILEGES".
The latter is defined with two variables: "PrivilegeCount As Long" and "Privileges(ANYSIZE_ARRAY) As LUID_AND_ATTRIBUTES"
"LUID_AND_ATTRIBUTES" defines two variables "pLuid As LUID" and "Attributes As Long"
"LUID" also defines two variables: "LowPart As Long" and "HighPart As Long"
Indeed, you are right, none of the 'lower' variables are of the LARGE_INTEGER type...
I guess that call is wrong then maybe? I mean, I shouldn't use "tkp.LUID" but something else (but that has to be LARGE_INTEGER)...
Sofar I think I was able to adjust variable-types to make everything 'fit' the 64-bit model, seems that this time however I should actually go change a call itself (and unless someone understands what's going on here, I think I'd need more background and understanding to do that).
Let's not lose my goal out of sight: I'd like to be able to read/write NTFS Alternate Data Streams via VBA code in MSO365 (64bit). I'm doing that now by trying to 'adapt' existing 32-bit code that I found on the Internet and used successfully before.
I'm not 'stuck' to that approach however... any other VBA code that works for 64-bit Office will be more than fine as well (but I searched and couldn't find anything yet)...
-
- BronzeLounger
- Posts: 1272
- Joined: 03 Feb 2010, 19:59
- Location: Terneuzen, the Netherlands
Re: CStreams 64bit?
So we're stuck I guess... and therefore there's no way (yet) to read/write ADS via VBA in a 64bit environment.
Any suggestions for other locations where I could post this question maybe then?
Any suggestions for other locations where I could post this question maybe then?
Last edited by ErikJan on 02 Feb 2024, 15:03, edited 1 time in total.