Why do both C++ Release versions compile OK, but not the Debug versions? (VS Community 2019)

Daniel Sedory 161 Reputation points
2021-03-14T04:43:37.403+00:00

Trying again! Server would not publish this earlier due to the code!

I have a C++ program that accesses a disk drive, copies data from it and writes the data to a file!

NOTE: I am using Visual Studio Community 2019 (Version 16.9.1); I have no idea if the problem I'm having exists in any other editions/versions!

I started in VS with new "Windows C++ Desktop" project; removed all the files that creates, and then edited the single .CPP file you see below. After that, I made sure to set the entry to "main" in "Advanced" under Linker in Properties. If you don't, you'll get a fatal compile error. AND be sure to do so with the configuration set to "Release" for either "Win32" or for "x64"; the program will create a fully functional .EXE for either of those settings.

Note: You must run the program with ADMIN. privileges or it will fail AND display a message that it can't access the disk drive. Also, if it succeeds, and you leave the file it writes in place, it will fail to write that file a second time (on purpose); obviously a whole lot more error messages could be added... but no need to complicate things for my question: WHY DOES DEBUG version FAIL?

HOWEVER, using the built-in settings for the "Debug" version; again either x64 or Win32, the compile FAILS! Here's the output from the "x64 Debug" (the Win32 Debug errors are similar, but not the same) try:

Build started...
1>------ Build started: Project: CopyDrvData, Configuration: Debug x64 ------
1>CopyDrvData.cpp
1>MSVCRTD.lib(init.obj) : error LNK2019: unresolved external symbol _CrtDbgReport referenced in function _CRT_RTC_INIT
1>MSVCRTD.lib(init.obj) : error LNK2019: unresolved external symbol _CrtDbgReportW referenced in function _CRT_RTC_INITW
1>MSVCRTD.lib(error.obj) : error LNK2019: unresolved external symbol strcpy_s referenced in function "void cdecl _RTC_StackFailure(void *,char const *)" (?_RTC_StackFailure@@YAXPEAXPEBD@Z)
1>MSVCRTD.lib(error.obj) : error LNK2019: unresolved external symbol strcat_s referenced in function "void __cdecl _RTC_StackFailure(void *,char const *)" (?_RTC_StackFailure@@YAXPEAXPEBD@Z)
1>MSVCRTD.lib(error.obj) : error LNK2019: unresolved external symbol __stdio_common_vsprintf_s referenced in function _vsprintf_s_l
1>MSVCRTD.lib(error.obj) : error LNK2001: unresolved external symbol __C_specific_handler_noexcept
1>MSVCRTD.lib(pdblkup.obj) : error LNK2019: unresolved external symbol _wmakepath_s referenced in function "int __cdecl GetPdbDllPathFromFilePath(wchar_t const *,wchar_t *,unsigned __int64)" (?GetPdbDllPathFromFilePath@@YAHPEB_WPEA_W_K@Z)
1>MSVCRTD.lib(pdblkup.obj) : error LNK2019: unresolved external symbol _wsplitpath_s referenced in function "int __cdecl GetPdbDllPathFromFilePath(wchar_t const *,wchar_t *,unsigned __int64)" (?GetPdbDllPathFromFilePath@@YAHPEB_WPEA_W_K@Z)
1>MSVCRTD.lib(pdblkup.obj) : error LNK2019: unresolved external symbol wcscpy_s referenced in function "int __cdecl GetPdbDllPathFromFilePath(wchar_t const *,wchar_t *,unsigned __int64)" (?GetPdbDllPathFromFilePath@@YAHPEB_WPEA_W_K@Z)
1>MSVCRTD.lib(pdblkup.obj) : error LNK2019: unresolved external symbol __vcrt_GetModuleFileNameW referenced in function "struct HINSTANCE
* cdecl GetPdbDll(void)" (?GetPdbDll@@YAPEAUHINSTANCE@@XZ)
1>MSVCRTD.lib(pdblkup.obj) : error LNK2019: unresolved external symbol vcrt_GetModuleHandleW referenced in function "struct HINSTANCE * cdecl GetPdbDll(void)" (?GetPdbDll@@YAPEAUHINSTANCE@@XZ)
1>MSVCRTD.lib(pdblkup.obj) : error LNK2019: unresolved external symbol vcrt_LoadLibraryExW referenced in function "struct HINSTANCE * cdecl GetPdbDll(void)" (?GetPdbDll@@YAPEAUHINSTANCE@@XZ)
1>C:\Users\user\source\repos\CopyDrvData\x64\Debug\CopyDrvData.exe : fatal error LNK1120: 12 unresolved externals
1>Done building project "CopyDrvData.vcxproj" -- FAILED.

==========
Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

I'm just starting to work with C++, so right now my only guess is that maybe there is some kind of HEADER/LIBRARY for DEBUG that is needed to do that??

Let's see if I can enter the code here as plain TEXT (with a "\" before "#" and you must also convert the "Read-File" to "ReadFile"):

// NOTE: CopyDrvData needs Admin privileges!

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

int main() {

const LPCSTR szFileName = "\\.\PhysicalDrive0";
const LPCSTR pFileName = ".\Drv0Data";
const LPCSTR winCapt = "CopyDrvData - Copies Data from Drv0 to a File";
const LPCSTR noAccDrv0 = "Unable to access Drv0!\n\nCopyDrvData received \
an INVALID_HANDLE_VALUE to its request to access Drv0.";
const LPCSTR RdFileFail = "CopyDrvData was able to access the first Drive, \
but for some unknown reason the ReadFile Function failed!";
const LPCSTR WrtFileFail = "CopyDrvData was able to access the first Drive, \
but for some reason failed to write the data to a File!";
const LPCSTR OpOKTxt = "CopyDrvData to File \"Drv0Data\" was successful.";

HANDLE hFile;
LPDWORD pnBytes = 0;
unsigned char DatBuff[512];

//First we need to obtain an "open DASD (direct access storage device) handle" to the
//PC's first Disk (\.\PhysicalDrive0) in order to actually read data from it using:
//https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
//which includes interacting with I/O devices, such as physical disks, volumes and
//directories! If "CreateFileA" provides us with an "open handle" to the disk, then
//Data will be read from it much further below using the ReadFile Function!

hFile = CreateFileA (szFileName, GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ,
0, OPEN_EXISTING, 0, 0);
if (hFile == INVALID_HANDLE_VALUE) {
MessageBoxA (NULL, noAccDrv0, winCapt, MB_ICONINFORMATION);
return -1; // Set exit code to "-1".
}

// Now READ the desired data bytes from the first Disk using function "ReadFile":
// https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-readfile

if (
Read-File ( // If possible, read first 512 bytes from Disk.
hFile, // Open Device Handle
DatBuff, // lpBuffer
512, // nNumberOfBytesToRead
pnBytes, // Pointer to lpNumberOfBytesRead
NULL // lpOverlapped is set to NULL
)
== FALSE)
{ // If the operation failed, inform user:

MessageBoxA (NULL, RdFileFail, winCapt, MB_ICONINFORMATION);
return 0;
}

CloseHandle (hFile); // Close the open handle (hObject) to the disk drive.

hFile = CreateFileA ( // Attempt to access device for reading!
pFileName, // lpFileName = Pointer to Filename.
GENERIC_WRITE, // _dwDesiredAccess.
NULL, // dwShareMode
NULL, // lpSecurityAttributes
CREATE_NEW, // dwCreationDisposition
FILE_ATTRIBUTE_NORMAL, // dwFlagsAndAttributes
NULL // hTemplateFile
);

// Now the Data in the Buffer can be written to the new "Drv0Data"
// file using the WriteFile Windows API Function:

if (
WriteFile (
hFile, // hFile is the "handle" required to access the file.
DatBuff, // A pointer to where the data to be written is located.
512, // The nNumberOfBytesToWrite value.
pnBytes, // Pointer to where lpNumberOfBytesWritten value is.
NULL) // lpOverlapped set to NULL for our purposes.
== FALSE) { // If the operation failed, inform user:

MessageBoxA (NULL, WrtFileFail, winCapt, MB_ICONINFORMATION);
return 0;
}

CloseHandle (hFile); // Close the open handle (hObject) to the disk drive.

// Inform user MBR has been copied and how to view it:

MessageBoxA (NULL, OpOKTxt, winCapt, MB_ICONINFORMATION);

return 0;
}

TIA, Dan, TheStarman.

C++
C++
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,527 questions
Visual Studio Debugging
Visual Studio Debugging
Visual Studio: A family of Microsoft suites of integrated development tools for building applications for Windows, the web and mobile devices.Debugging: The act or process of detecting, locating, and correcting logical or syntactical errors in a program or malfunctions in hardware. In hardware contexts, the term troubleshoot is the term more frequently used, especially if the problem is major.
939 questions
{count} votes

Accepted answer
  1. WayneAKing 4,921 Reputation points
    2021-03-15T01:29:24.533+00:00

    (Left all files as is and the "framework.h" and "WindowsProject1.h"
    in .cpp, but still had to change to "main()" though.*)

    If I left it as wWinMain(), none compiled, complaining function
    was "overloaded".

    For starters, you should not be using the project template
    "Windows Desktop Application." For the code you are building
    you should use the template "Console App".

    In the context of project templates, a "Windows Desktop
    Application" means a GUI application with WinMain(), a message
    pump. message handlers, etc. That template generates a lot of
    extra code and project settings that are not needed (or correct
    in some cases) for the type of program you are building.

    • Wayne

2 additional answers

Sort by: Most helpful
  1. Dylan Zhu-MSFT 6,406 Reputation points
    2021-03-15T06:53:19.077+00:00

    Hi DanielSedory,

    As Wayne says, the desktop project needs to start with WinMain(). And you cannot set main function as entry point.

    In addition to using console application, maybe you can use this method to manually create a C++ winform project: https://social.msdn.microsoft.com/Forums/vstudio/en-US/e6fbde42-d872-4ab3-8000-41ab22a4a584/visual-studio-2017-windows-forms?forum=winformsdesigner

    Best Regards, Dylan

    If the answer is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our * *documentation* to enable e-mail notifications if you want to receive the related email notification for this thread.**

    0 comments No comments

  2. WayneAKing 4,921 Reputation points
    2021-03-19T02:06:54.833+00:00

    Why does using the EMPTY C++ project; which is
    supposed to be for EITHER "Windows" or "Console"
    programs, still have the same problem (releases
    compiled OK, but not the Debug versions)?

    It's difficult, sometimes impossible, to diagnose
    configuration problems in a vacuum - without access
    to the actual project files, settings, etc. An "Empty"
    project is NOT one without dependencies, settings,
    properties, etc.

    These must be set properly, with due respect for inter-
    dependencies, etc. When you aren't quite familiar with
    all of the settings, their requirements and effects, etc.
    then one would be well advised to leave them alone. That's
    why the predefined project templates exist - to assist
    those of us who are less than expert in the intricacies
    involved.

    A Debug project has preset settings and requirements
    which a Release build doesn't. For example a Debug
    build must generate and use Program DataBases. Some
    other linker settings may be different, such as fast
    linking, incremental linking, etc.

    Note that the errors you have been getting are Linker
    errors, NOT compiler errors.

    I suspect that you made some invalid assumptions and
    hence some improper steps in configuring the properties
    for the empty project. I suggest you try again but this
    time follow these steps:

    When the project has been created and you have added
    your source file to it, go to the project properties and
    change the Subsystem to CONSOLE as I previously described.
    Do NOT set the Entry Point to main or anything else -
    leave it alone. Do a Build or Rebuild.

    The above assumes that you still have main() in your
    source code, and haven't changed it as I described in
    one of my later posts explaining the steps to take in
    order to eliminate the console window without using
    FreeConsole().

    I haven't seen any feedback from you as to success
    or failure following the steps I described in that
    post. To read it here in the forums you may have to
    click on the link which says "Show more comments".

    • Wayne
    0 comments No comments