Opening a file with CreateFile() returns invalid handle with error code 183

279 views Asked by At

I'm trying to open an existing file and write its content to a newly created file as a stream:

#include <Windows.h>
#include <stdio.h> 

#define BUFFER_LENGTH 2048 

int main(void) {
        BYTE    buffer[BUFFER_LENGTH];
        DWORD   readCount;
    
        // Program breaks here.
        HANDLE hReadFile = CreateFile(L"file.mp4", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hReadFile == INVALID_HANDLE_VALUE) {        
            printf("Error: %d\n", GetLastError());
            return 1;
        }
    
        HANDLE hWriteFile = CreateFile(L"out.mp4", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hWriteFile == INVALID_HANDLE_VALUE) {
            printf("Error: %d\n", GetLastError());
            CloseHandle(hReadFile);
            return 1;
        }
    
        while (ReadFile(hReadFile, buffer, BUFFER_LENGTH, &readCount, NULL) && readCount > 0) {
            if (!WriteFile(hWriteFile, buffer, BUFFER_LENGTH, &readCount, NULL)) {
                CloseHandle(hReadFile);
                CloseHandle(hWriteFile);
                printf("Error: %d\n", GetLastError());
                return 1;
            }
            memset(buffer, 0, sizeof(buffer));
        }
    
        CloseHandle(hReadFile);
        CloseHandle(hWriteFile);
        return 0;
    }

And the program exits with as CreateFile() returns an invalid handle. The error code is 183, as per docs (ERROR_ALREADY_EXISTS: Cannot create a file when that file already exists.).

Then I checked the result after comparing each handle individually:

HANDLE hReadFile = CreateFile(L"file.mp4", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
HANDLE hWriteFile = CreateFile(L"out.mp4", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

BOOL isInvalid_hRead = hReadFile == INVALID_HANDLE_VALUE;
BOOL isInvalid_hWrite = hWriteFile == INVALID_HANDLE_VALUE;

I put a breakpoint after these statements and this is the values of the variables: enter image description here

Why does the program throw this kind of error when I'm trying to open a file.

Edit: I navigated to the folder where the output executable is and ran it, and it worked as expected. But if I run the application from Visual Studio, the invalid handle returns.

1

There are 1 answers

0
Jabberwocky On

This is not really an answer, but this is a version that displays more information and with some corrected bugs mentioned in the comments.

Run this under your Visual Studio and show us the verbatim output you get.

#include <Windows.h>
#include <stdio.h> 

#define BUFFER_LENGTH 2048 

int main(void) {
  BYTE    buffer[BUFFER_LENGTH];
  DWORD   readCount;
  int rv = 0;

  printf("Test Program\n");
  WCHAR currentdir[_MAX_PATH];
  GetCurrentDirectory(_MAX_PATH, currentdir);
  wprintf(L"Current dir: %s\n", currentdir);

  HANDLE hReadFile = CreateFile(L"file.mp4", GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  if (hReadFile == INVALID_HANDLE_VALUE) {
    DWORD err = GetLastError();
    printf("Error %d opening input file.\n", err);
    return 1;
  }

  HANDLE hWriteFile = CreateFile(L"out.c", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  if (hWriteFile == INVALID_HANDLE_VALUE) {
    DWORD err = GetLastError();
    printf("Error %d opening output file.\n", err);
    CloseHandle(hReadFile);
    return 1;
  }

  do
  {
    if (!ReadFile(hReadFile, buffer, BUFFER_LENGTH, &readCount, NULL))
    {
      DWORD err = GetLastError();
      printf("Error %d while reading file.\n", err);
      rv = 1;
      break;
    }
    
    if (readCount > 0)
    {
      DWORD writeCount;
      if (!WriteFile(hWriteFile, buffer, readCount, &writeCount, NULL)) {
        DWORD err = GetLastError();
        printf("Error %d while writing file.\n", err);
        rv = 1;
        break;
      }

      if (readCount != writeCount)
      {
        printf("readCount (%d) is different from writeCount (%d). This is unlikely to happen.\n", readCount, writeCount);
      }
    }
  } while (readCount);

  CloseHandle(hReadFile);
  CloseHandle(hWriteFile);
  return rv;
}