0

I've just written a C program (Ubuntu platform, using GCC as my compiler) where I have a big chunk of memory, all populated with meaningful data:

u_char* bigChunkOfMem = populateData();       // This works
int memSize = sizeOfChunk( bigChunkOfMem );   // This also works

The trouble is, I need to submit this data to another function, which I did not write. This function takes a File Descriptor as input, so I need to copy my data into a tempfile:

FILE* myTmpFile = tmpfile();

printf("Now copying contents of bigChunkOfMem into myTmpFile!\n");
int i=0;
while( i < memSize ){
    fputc( bigChunkOfMem[i], myTmpFile );
    printf("...just copied bigChunkOfMem[%d]:%u\n", i, bigChunkOfMem[i]);
    i++;
}
printf("\n");
rewind( myTmpFile );

I guess this is working...? My output is this:

Now copying contents of bigChunkOfMem into myTmpFile!
...just copied bigChunkOfMem[0]:101
...just copied bigChunkOfMem[1]:102
...just copied bigChunkOfMem[2]:103
...and so on...

But of course, I submit myTmpFile to the other function, and nothing happens. The other function isn't processing my data.

Its entirely possible my data is incorrectly formatted. But let's set that aside for the moment. In my troubleshooting, it really bothers me that I don't have a way to inspect the tempfile after it is created. I tried using fread():

char[200] buffer;
fread( buffer, memSize+1, 1, myTmpFile );
printf("buffer is:: %s\n", buffer);
rewind( myTmpFile );

But that didn't seem to work. Output was:

buffer is:: [[not my data]]

I assume that a temp file is no logically different than a "regular" file written to disk, i.e., I should be able to inspect the temp file with all the same tools I use for any other file. Is this correct? The online documentation implies this, but I can't find any source that confirms this. Thank you.

Pete
  • 1,511
  • 2
  • 26
  • 49
  • Please [edit] your question and show the prototype of the _"the other function"_ you mention as well as your code that calls it. Generally it's better to show your code rather than describing it. – Jabberwocky Sep 08 '20 at 07:30

2 Answers2

1

Please try this code,To How to Inspect a Temp File in C?

#include <windows.h>
#include <tchar.h>
#include <stdio.h>

#define BUFSIZE 1024

void PrintError(LPCTSTR errDesc);

int _tmain(int argc, TCHAR *argv[])
{
    HANDLE hFile     = INVALID_HANDLE_VALUE;
    HANDLE hTempFile = INVALID_HANDLE_VALUE; 

    BOOL fSuccess  = FALSE;
    DWORD dwRetVal = 0;
    UINT uRetVal   = 0;

    DWORD dwBytesRead    = 0;
    DWORD dwBytesWritten = 0; 

    TCHAR szTempFileName[MAX_PATH];  
    TCHAR lpTempPathBuffer[MAX_PATH];
    char  chBuffer[BUFSIZE]; 

    LPCTSTR errMsg;

    if(argc != 2)
    {
        _tprintf(TEXT("Usage: %s <file>\n"), argv[0]);
        return -1;
    }

    //  Opens the existing file. 
    hFile = CreateFile(argv[1],               // file name 
                       GENERIC_READ,          // open for reading 
                       0,                     // do not share 
                       NULL,                  // default security 
                       OPEN_EXISTING,         // existing file only 
                       FILE_ATTRIBUTE_NORMAL, // normal file 
                       NULL);                 // no template 
    if (hFile == INVALID_HANDLE_VALUE) 
    { 
        PrintError(TEXT("First CreateFile failed"));
        return (1);
    } 

     //  Gets the temp path env string (no guarantee it's a valid path).
    dwRetVal = GetTempPath(MAX_PATH,          // length of the buffer
                           lpTempPathBuffer); // buffer for path 
    if (dwRetVal > MAX_PATH || (dwRetVal == 0))
    {
        PrintError(TEXT("GetTempPath failed"));
        if (!CloseHandle(hFile))
        {
            PrintError(TEXT("CloseHandle(hFile) failed"));
            return (7);
        }
        return (2);
    }

    //  Generates a temporary file name. 
    uRetVal = GetTempFileName(lpTempPathBuffer, // directory for tmp files
                              TEXT("DEMO"),     // temp file name prefix 
                              0,                // create unique name 
                              szTempFileName);  // buffer for name 
    if (uRetVal == 0)
    {
        PrintError(TEXT("GetTempFileName failed"));
        if (!CloseHandle(hFile))
        {
            PrintError(TEXT("CloseHandle(hFile) failed"));
            return (7);
        }
        return (3);
    }

    //  Creates the new file to write to for the upper-case version.
    hTempFile = CreateFile((LPTSTR) szTempFileName, // file name 
                           GENERIC_WRITE,        // open for write 
                           0,                    // do not share 
                           NULL,                 // default security 
                           CREATE_ALWAYS,        // overwrite existing
                           FILE_ATTRIBUTE_NORMAL,// normal file 
                           NULL);                // no template 
    if (hTempFile == INVALID_HANDLE_VALUE) 
    { 
        PrintError(TEXT("Second CreateFile failed"));
        if (!CloseHandle(hFile))
        {
            PrintError(TEXT("CloseHandle(hFile) failed"));
            return (7);
        }
        return (4);
    } 

    //  Reads BUFSIZE blocks to the buffer and converts all characters in 
    //  the buffer to upper case, then writes the buffer to the temporary 
    //  file. 
    do 
    {
        if (ReadFile(hFile, chBuffer, BUFSIZE, &dwBytesRead, NULL)) 
        {
            //  Replaces lower case letters with upper case
            //  in place (using the same buffer). The return
            //  value is the number of replacements performed,
            //  which we aren't interested in for this demo.
            CharUpperBuffA(chBuffer, dwBytesRead); 

            fSuccess = WriteFile(hTempFile, 
                                 chBuffer, 
                                 dwBytesRead,
                                 &dwBytesWritten, 
                                 NULL); 
            if (!fSuccess) 
            {
                PrintError(TEXT("WriteFile failed"));
                return (5);
            }
        } 
        else
        {
            PrintError(TEXT("ReadFile failed"));
            return (6);
        }
    //  Continues until the whole file is processed.
    } while (dwBytesRead == BUFSIZE); 

    //  The handles to the files are no longer needed, so
    //  they are closed prior to moving the new file.
    if (!CloseHandle(hFile)) 
    {
       PrintError(TEXT("CloseHandle(hFile) failed"));
       return (7);
    }
    
    if (!CloseHandle(hTempFile)) 
    {
       PrintError(TEXT("CloseHandle(hTempFile) failed"));
       return (8);
    }

    //  Moves the temporary file to the new text file, allowing for differnt
    //  drive letters or volume names.
    fSuccess = MoveFileEx(szTempFileName, 
                          TEXT("AllCaps.txt"), 
                          MOVEFILE_REPLACE_EXISTING | MOVEFILE_COPY_ALLOWED);
    if (!fSuccess)
    { 
        PrintError(TEXT("MoveFileEx failed"));
        return (9);
    }
    else 
        _tprintf(TEXT("All-caps version of %s written to AllCaps.txt\n"), argv[1]);
    return (0);
}

//  ErrorMessage support function.
//  Retrieves the system error message for the GetLastError() code.
//  Note: caller must use LocalFree() on the returned LPCTSTR buffer.
LPCTSTR ErrorMessage(DWORD error) 
{ 
    LPVOID lpMsgBuf;

    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER 
                   | FORMAT_MESSAGE_FROM_SYSTEM 
                   | FORMAT_MESSAGE_IGNORE_INSERTS,
                  NULL,
                  error,
                  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
                  (LPTSTR) &lpMsgBuf,
                  0,
                  NULL);

    return((LPCTSTR)lpMsgBuf);
}

//  PrintError support function.
//  Simple wrapper function for error output.
void PrintError(LPCTSTR errDesc)
{
        LPCTSTR errMsg = ErrorMessage(GetLastError());
        _tprintf(TEXT("\n** ERROR ** %s: %s\n"), errDesc, errMsg);
        LocalFree((LPVOID)errMsg);
}

I hope this code will be useful for you.

Thank you.

Makwana Prahlad
  • 1,025
  • 5
  • 20
  • This code is specific to Windows. The OP didn't mention he's on Windows. – Jabberwocky Sep 08 '20 at 07:26
  • Yes, I apologize, I should have mentioned... I'm on an Ubuntu system, compiling with GCC. I'll edit my posting, and see if I can't adapt your code. Thank you! – Pete Sep 08 '20 at 10:27
  • @Pete this code is very Windows specific, I doubt you can use any of in on Linux. – Jabberwocky Sep 08 '20 at 10:29
  • @Jabberwocky Yes, you were correct, I wasn't able to adapt. But thank you Makwana, you gave me some good ideas. :) – Pete Sep 08 '20 at 19:15
0

For what its' worth, I realized I could inspect a tmp file like any other file; open and read it. Here is code that works from here:

void readTmpFile( FILE* f ){
        u_char * buffer = 0;
        long length;
        //FILE * f = fopen (filename, "rb");

        if (f) {
                fseek (f, 0, SEEK_END);
                length = ftell (f);
                fseek (f, 0, SEEK_SET);
                buffer = malloc (length);
                int dontcare = 0;
                if (buffer){
                        dontcare = fread (buffer, 1, length, f);
                }
        fclose (f);
        }

        printPCAP_RAW( buffer, 1 );

        free( buffer );
}
Pete
  • 1,511
  • 2
  • 26
  • 49