PRB: GetTempFileName API Function May Fail on 32-bit Platforms

Last reviewed: October 10, 1996
Article ID: Q137034
The information in this article applies to:
  • Standard, Professional, and Enterprise Editions of Microsoft Visual Basic, 16-bit and 32-bit, for Windows, version 4.0

SUMMARY

GetTempFileName is an API function used to create a temporary filename. Although this function is supported on both 16-bit and 32-bit platforms, minor differences in its calling conventions exist. Additionally, when used with a 32-bit platform such as Windows 95 or Windows NT, GetTempFileName might fail. This article discusses the function's cross-platform portability and explains the cause and resolution of its failure on 32-bit platforms.

SYMPTOMS

When using the GetTempFileName API function on a 32-bit platform, one of the following symptoms may appear:

  • The function passes back a null parameter for the filename and returns 0. This is more likely to happen in Windows NT.
  • The function passes back a pathname without a filename and returns 0. This more likely to happen in Windows 95.

CAUSE

Contrary to its usage on 16-bit platforms where only the drive letter is passed, GetTempFileName requires you to pass the drive letter and the pathname when used on 32-bit platforms. Furthermore, the pathname specified must contain existing directories. For example, examine the following function declarations:

  • For 16-bit platforms such as Windows 3.1 and Windows for Workgroups:

       Declare Function GetTempFileName Lib "Kernel" (ByVal cDriveLetter as _
          Integer, ByVal lpPrefixString As String, ByVal wUnique As Integer, _
          ByVal lpTempFileName As String) As Integer
    
    
  • For 32-bit platforms such as Windows NT and Windows 95:

       Private Declare Function GetTempFileName Lib "kernel32" _
          Alias "GetTempFileNameA" (ByVal lpszPath As String, _
          ByVal lpPrefixString As String, ByVal wUnique As Long, _
          ByVal lpTempFileName As String) As Long
    
    
Notice how the first parameter is the only parameter that changes in the declarations. In 16-bit, the first parameter is an integer representing a drive letter. The pathname is specified by the function not by the user (see the Visual Basic 3.0 Windows 3.1 SDK help file for more information).

In 32-bit, however, the first parameter is a string that gives the pathname. So if you were to cease a temporary file in the C drive root directory, the first parameter will be assigned a different value for each case:

  • For 16-bit: cDriveLetter = 2 (Integer representation of drive C)
  • For 32-bit: lpszPath = "C:\"

If lpszPath is an invalid path or if it contains a nonexistent directory, GetTempFileName will pass back the lpTempFileName parameter with a null value or with a pathname only. The return value of the function in both cases will be zero.

STATUS

This behavior is by design.

MORE INFORMATION

Steps to Reproduce and Resolve Behavior

  1. Create a new project in 32-bit Visual Basic 4.0. Form1 is created by default.

  2. Copy the following code into the General Declarations section of Form1:

       Private Declare Function GetTempFileName Lib "kernel32" _
          Alias "GetTempFileNameA" (ByVal lpszPath As String, _
          ByVal lpPrefixString As String, ByVal wUnique As Long, _
          ByVal lpTempFileName As String) As Long
    
       Private Sub Form_Click()
          Dim lpszPath As String
          Dim lpPrefixString As String
          Dim wUnique As Long
          Dim lpTempFileName As String
    
          ' Because the C:\windows directory, probably, doesn't exist,
          ' using this line will cause the problem to occur:
          lpszPath = "C:\windows"     ' Line A
    
          ' To resolve the problem, change the previous line into a comment
          ' and change the following line from a comment into an executed line:
          ' lpszPath = "C:\windows"    ' Line B
    
          lpPrefixString = "shn"
    
          ' If wUnique is nonzero, it will be appended
          ' to the temporary filename. If the parameter is zero,
          ' Windows uses the current system time to create a
          ' number to append to the filename.
          wUnique = 0
    
          ' Initialize variable
          lpTempFileName = Space$(100)
          Print GetTempFileName(lpszPath, lpPrefixString,_
             wUnique, lpTempFileName)
    
          ' If running under Windows 95, use the following line to get
          ' rid of the null character
          ' Print Mid$(lpTempFileName, 1, InStr(lpTempFileName, Chr$(0)) - 1)
          Print lpTempFileName
       End Sub
    
    

  3. Start the program by pressing the F5 key.

  4. Notice how the problem is reproduced. Change Line A into a comment and make Line B into an executed line. Then repeat step 3. The problem should now disappear.


Additional reference words: 4.00 vb4win vb4all
KBCategory: kbprg kbcode kbprb
KBSubcategory: APrgOther


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: October 10, 1996
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.