FileExists Inline ASM

Hi i am trying to write a function using INLINE ASM to determine if a file exists using GetFileAttributesA in Kernel32.dll.

Here is my code:

bool fileExists(long memAddr)
{
      bool retVal;
      __asm
      {
            invoke GetFileAttributesA,addr memAddr
            cmp   eax,-1
            je      LBL1
            mov   ebx,01h
            jmp   LBL3
            LBL1:
            mov  ebx,00h
            LBL3:
            mov  retVal,ebx
      }
      return retVal;


i know invoke is MASM style ASM, but how can I do this in C++, all I need to know is how to call the  GetFileAttributesA function using ASM, and I can do the rest, also as you can see I am passing a long value into the function which will be the address of the string. I need to know how to call the function so I am passing the address, (i dont think this is a pass by reference deal).

-Brian
LVL 19
BrianGEFF719Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

grg99Commented:
Any particular reason you're using asm?   Hint:  Speed isnt a very good reason.

0
AxterCommented:
I completely agree with grg99.

There's no pratical reason for calling GetFileAttributesA via ASM.

That's just going to make the code harder to debug, and none-portable with no benifit.
0
GrayGh0stCommented:
Also not sure why one would use inline assmebly...

I'm not familiar with the GetFileAttributes function, but if you do decide to do it in c++, you might be tempted to use the ios::noreplace flag to open the file and then check one of the status bits... Be careful b/c if I'm not mistaken, ios::noreplace may not be standard compliant. Sun/Solaris or gcc doesn't support it, can't remember which one. A workaround would be something like:

bool fileExists(const string& fileName) {
    fstream test(fileName, ios::in);
    return !test ? false : true;
}

-Justin
0
Cloud Class® Course: Microsoft Azure 2017

Azure has a changed a lot since it was originally introduce by adding new services and features. Do you know everything you need to about Azure? This course will teach you about the Azure App Service, monitoring and application insights, DevOps, and Team Services.

AxterCommented:
I don't recommend trying to open a file to test for file existance.  It's not reliable and it's inefficient.

A cleaner, more efficient and more reliable way to check for file existance is to use stat or access function.
Example:

#include <sys/stat.h>
#include <io.h>
#include <direct.h>

bool FileExist(const char* FileName)
{
   struct stat my_stat;
   return (stat(FileName, &my_stat) == 0);
}

bool IsDirectory(const char* FileName)
{
   struct stat my_stat;
   if (stat(FileName, &my_stat) != 0) return false;
   return ((my_stat.st_mode & S_IFDIR) != 0);
}

Example code for access function.

#include  <io.h>
#include  <stdio.h>
#include  <stdlib.h>

void main( void )
{
   /* Check for existence */
   if( (_access( "FileName.Ext", 0 )) != -1 )
   {
      printf( "File FileName.Ext exists\n" );
   }
}
0
BrianGEFF719Author Commented:
okay, I want to use ASM to do this, no particular reason, so can I please get help with my original question.


-Brian
0
grg99Commented:
Okay, if you must.

The system API's use the old Pascal calling sequence, whereein the parameters are pushed onto the stack from left to right.

In your case just push the address of the file name before the call to GetFileAttributes.

You might want to change your function to take a char * parameter, not a long, that would make it more convenient to call.

0
BrianGEFF719Author Commented:
Okay, so if the function Takes Char * can you give me an example of how to push the address of that Char * so i can push it to the stack, and how would I call the GetFileAttributesA function, thats the biggest part.
0
grg99Commented:

   bool fileExists( char * FileName )
{
_asm {
    push   FileName
    call     GetFileAttributes
   ....
}

0
BrianGEFF719Author Commented:
Here is my code:

bool fileExists(char * fileName)
{
      __asm
      {
            lea    eax,fileName
            push   eax
            xor    eax,eax
            call   GetFileAttributes
            cmp    eax,-1
            je     LBL1
            mov         eax,01h
            jmp    LBL2
            LBL1:
            mov    eax,00h
            LBL2:
            mov    fileExists,eax
      }
}


I am calling like this:

cout << fileExists("c:\autoexec.bat");


I am erroring for some reason:
Unhandled exception at 0x0045a1c5 in fileExists.exe: 0xC0000005: Access violation reading location 0xffffffff.


Suggestions?
0
BrianGEFF719Author Commented:
when debugging what happens after the LEA fileName, EAX = 0x0012FDF8

value in that location:
ÈðD.O[&#145;|@....àýÌÌÌÌ

junk its not the value I passed to the function?

Whats up?

0
BrianGEFF719Author Commented:
okay, I changed to:

mov eax, fileName

Now I have the correct memory address...

-Brian
0
BrianGEFF719Author Commented:
But I am still erroring...

Exact Code:

bool fileExists(char * fileName)
{
      __asm
      {
            mov   eax,fileName
            push   eax          
            xor    eax,eax        
            call   GetFileAttributes  
            cmp    eax,-1            
            je     LBL1              
            mov         eax,01h          
            jmp    LBL2            
            LBL1:                    
            mov    eax,00h          
            LBL2:
            mov    fileExists,eax
      }
}
0
BrianGEFF719Author Commented:
the getFileattributes function is failing on

pop ss


whats wrong?

-brian
0
grg99Commented:
I'd do a call to getfileattrributes from a C program, then use the debugger to see exactly what code it generated.  You probably don't need the xor ax,ax.  And if that API ins in a system DLL, the call might have to be an indirect call "call dword ptr [GetFilettributes].   Best way to figure out the calling protocol is to see what code C generates.

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
BrianGEFF719Author Commented:
grg99: thanks you were right it was an indirect call.

bool fileExists(char * fileName)
{
      bool retVal;
      __asm
      {
            mov    eax,fileName
            push   eax              
            call   dword ptr [GetFileAttributesA]
            cmp    eax,-1            
            je     LBL1              
            mov         eax,01h          
            jmp    LBL2            
            LBL1:                    
            mov    eax,00h          
            LBL2:
            mov   retVal,al
      }
      return retVal;
}


got it working :)
0
BrianGEFF719Author Commented:
full code incase anyone wants it:

#include <iostream>
#include <string>
#include <windows.h>

bool fileExists(char * fileName);
using namespace std;

int main()
{
      char * fileName;
      fileName = "c:\\autoexec.bat";

      if (fileExists(fileName) == false)
       cout << fileName << " does not exist";
      else
       cout << fileName << " exists!";

      cout << endl;
      system("PAUSE");
return 0;
}

bool fileExists(char * fileName)
{
      bool retVal;
      __asm
      {
            mov    eax,fileName
            push   eax
            mov    eax, dword ptr [GetFileAttributesA]
            call   eax
            cmp    eax,00            
            jle    LBL1              
            mov         al,01          
            jmp    LBL2          
            LBL1:                    
            mov    al,00
            LBL2:
            mov    retVal,al
      }
      return retVal;
}
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.