Windows 64 and 32 bit VBA error

SjCc

Registered User.
Local time
Today, 07:00
Joined
Oct 5, 2017
Messages
67
I have prepared a db in windows 32 and now using 64 bit and getting error that you must be ...... the code is below and and i want to use it in both 32 and 64 bit windows system.. any help would be appreciated..


Option Compare Database

Public Declare Function apiGetUserName Lib "advapi32.dll" Alias _
"GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long

Public Function fOSUserName() As String
' Returns the network login name
Dim lngLen As Long, lngX As Long
Dim strUserName As String
strUserName = String$(254, 0)
lngLen = 255
lngX = apiGetUserName(strUserName, lngLen)
If (lngX > 0) Then
fOSUserName = Left$(strUserName, lngLen - 1)
Else
fOSUserName = vbNullString
End If
End Function
 
You need to add conditional compiling to the declaration line.
Rather than give you the answer, better that you learn how to do this yourself for future reference.

AWF member sonic8 has a good guide here https://codekabinett.com/rdumps.php?Lang=2&targetDoc=windows-api-declaration-vba-64-bit

Alternatively, scrap the existing code completely and replace with
Code:
Environ("UserName")
This needs no declaration and works in both 32-bit and 64-bit systems.

You should also tick Require Variable Declaration in the VBE options.
This will add the line Option Explicit as the second line of all new code modules. You will need to add this manually to all existing modules. Then run Debug..Compile and fix any errors
 
Try:

Code:
#If Win64 = 1 And VBA7 = 1 Then
     Public Declare PtrSafe Function apiGetUserName Lib "advapi32.dll" Alias _
"GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long      
#Else
     Public Declare Function apiGetUserName Lib "advapi32.dll" Alias _
"GetUserNameA" (ByVal lpBuffer As String, nSize As Long) As Long   
#End If

Public Function fOSUserName() As String
' Returns the network login name
     Dim lngLen As Long, lngX As Long
     Dim strUserName As String
     strUserName = String$(254, 0)
     lngLen = 255
     lngX = apiGetUserName(strUserName, lngLen)

     If (lngX > 0) Then
          fOSUserName = Left$(strUserName, lngLen - 1)
     Else
          fOSUserName = vbNullString
     End If
End Function
 
Sorry Col, didn't see that you had already replied!
 
No worries.
For info, you don't really need =1 or to test for both Win64 and VBA7 unless v2007 may be used.
Does nSize need LongPtr?
 
Last edited:
Thanks for the tip...I simply plagirized from ChrisO so I have NO idea about nSize needing LongPtr. One of the reasons I will never rise any higher than the ranks of Contender!
 
Alternatively, scrap the existing code completely and replace with
Code:
Environ("UserName")
This needs no declaration and works in both 32-bit and 64-bit systems.

I have often thought the same thing but it never occured to me why others use this API method instead. Did Environ() not exist in the recent past?
 
The fOSUserName function has been around for over 20 years. Think it came from Dev Ashish originally. No idea how long Environ has been in use but I think about as long. Whether one has any advantage over the other, I don't know...so I normally use the simplest method available

I haven't tested whether nSize needs LongPtr.
It depends if its a pointer. Not sure without checking. I raised it just in case.
 
I have often thought the same thing but it never occured to me why others use this API method instead. Did Environ() not exist in the recent past?
Environ can be spoofed very easily; the API call cannot.
Environ just retrieves an environment variable by name. Any user can set any of the user level environment variables to any value of his discretion.
 
Environ can be spoofed very easily; the API call cannot.
Environ just retrieves an environment variable by name. Any user can set any of the user level environment variables to any value of his discretion.

Another ancient mystery solved!
 
Environ can be spoofed very easily; the API call cannot.
Environ just retrieves an environment variable by name. Any user can set any of the user level environment variables to any value of his discretion.

Hi Phillip
Yes I'm aware of that & indeed have the code to do so .... and used it when testing my security challenges

However I've never really been concerned about that for two reasons:
1. AFAIK that's not possible to do if an app is compiled as an ACCDE so the code isn't available.
2. Changing the user name externally has no effect when Access is opened subsequently i.e. I still get the 'real' user name not what I changed it to. I've just tested that to make sure I'm correct

Am I missing something obvious?

Thanks for confirmation re the nSize argument
 
Last edited:
1. AFAIK that's not possible to do if an app is compiled as an ACCDE so the code isn't available.
Irrelevant!


Am I missing something obvious?
Yes!
You have been puzzling everyone, including me, with your security challenges. So, instead of solving this right away, I leave you some time to figure it out.
For now, just a tiny hint: How?
 
So I'm going to have to do some real work now!!!!
Hoisted by my own petard! ;)

Oh and thanks for the apparently non-hint!!!!!
 
Oh yes...now this is entertainment!!! Phil, you just made my day!
 
In a tightly-controlled domain-based environment with automated download of restrictive personal security profiles based on personal login ID, Environ("Username") is reliable, or at least it was approved by the U.S. Navy as acceptable even on a "sensitive" network. (But then again, the Navy didn't have wide-open networks anyway.)

In less tight situations, not so secure. It is always going to depend on whether the user can write to his/her own environment variables.
 
Oh yes...now this is entertainment!!! Phil, you just made my day!

Ok here's the encore.
After an hour or so of trying, I finally worked out how to spoof environ username to give a different result.
As Phillip stated, it is indeed very easy to do.... when you know how.

However, having read how easy it was to do on numerous sites, not one of those gave the solution .... and I'm not going to do so either. It isn't something that users will ever do by accident.

All I will say is that if it's important enough to ensure that the user name isn't spoofed, use a different method such as the fOSUserName function by Dev Ashish or this alternative that needs no api declarations
Code:
CreateObject("WScript.Network").UserName
 
Just thought I'd upload the DB I used when testing this.

It includes 3 methods of getting user name: Environ/WScript/fOSUserName
AFAIK only the first method can be spoofed.

attachment.php


Both ACCDB & 32-bit ACCDE versions attached to show ACCDE is indeed irrelevant here as Phil Stiefel (sonic8) stated.
 

Attachments

I've actually gotten out of the habit of using Environ("USERNAME") because it periodically, for no reason I could ascertain, returns an empty string on me. It's a pretty rare occurrence, but it was a showstopper all three times I encountered it. I may just switch to that WScript, though, since it avoids an API call, making future maintenance, especially if I'm gone, much easier.
 

Users who are viewing this thread

Back
Top Bottom