I am using Visual Studio 2022 on a Windows 10 platform, and have created a function in C to prevent overwriting a file. It makes use of getSuffix() and fileExists(), which are two functions that I had previously created and tested, and work correctly. The function protectWriteFile() should be called before an attempt is made to open a file for writing. The extension argument *ex, should be "hard-coded" in the function call, and if the filename with the extension does not match the extension, a negative value is returned indicating that it is invalid to open the file for writing. A zero return value indicates that the file does not exist and can be created and written to, and a postive return value indicates that the file already exists and should be safe to overwrite.
The function protectWriteFile() is listed as follows:
int protectWriteFile(CCHAR* fn, CCHAR* ex) { char exten[EXTEN_LEN] = { 0 }; int suffixLen = getSuffix(fn, EXTEN_LEN, '.', '\0', exten); if (suffixLen <= 0) return -1; if (strcmp(ex, exten) != 0) return -2; if (!fileExists(fn)) return 0; return 1; } In the calling function I have the following:
errno_t fileErr = 0; char logFn[FNAME_LEN] = { 0 }; printf("Type the output log filename: "); scanf_s("%s", logFn, FNAME_LEN); if (protectWriteFile(logFn, "log") < 0) { printf("*** ERROR: An invalid file extionsion that is not \"log\" is provided ***\n"); return 1; } fileErr = fopen_s(&logFp, logFn, "w"); if (fileErr) { printf("*** There is an error when attempting to open the log file ***\n"); return 1; } where the file is opened for writing if a non-negative value is returned. This works correctly.
However, I want to be able to test if the file is read-only without opening the file first, so some code should be added after the return 0 in the function, and will also return a negative value if the file is read-only.
Looking at some documentation online, the header <windows.h> should be included, then the following code between return 0 and return 1 in my function should be added:
DWORD fileAttr = GetFileAttributesA(fn); if (fileAttr == INVALID_FILE_ATTRIBUTES) return -3; if (file_attributes & FILE_ATTRIBUTE_READONLY) retun -4; This reads the file atrributes and finds if the file has invalid attributes or is read-only, and returns the appropriate negative value.
However in adding the line #include <windows.h> in my header, the compiler generates a large number of errors due to the fact that in my header I have several typdefs, such as
typedef const uint32_t CUINT;
which apparently collide with the typdefs in <windows.h>. I have too much code to be able to change this, so there must be some other solution. My question is, how do I use either the last bit of code listed above, or some equaivalent code on a Windows platform to be able to test a file without first opening it?
#include <windows.h>, then I recommend that you put all functions that need#include <windows.h>into a separate.cfile. That way, most of your project will be unaffected by you using#include <windows.h>.Windows.hin a header so just stay away from defining types that collides with those you get fromWindows.h. You should in most situations use the types already defined byWindows.hinstead."wx"to open the file instead. It will fail if the file already exists or create and open it if it doesn't exist atomically. No need to check before trying to open it.