[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 613
  • Last Modified:

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
0
BrianGEFF719
Asked:
BrianGEFF719
  • 9
  • 4
  • 2
  • +1
1 Solution
 
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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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
 
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

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 9
  • 4
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now