c++constantscreatefilelpwstr

C++ #define LPWSTR?


Ok, i have a problem in my program. I made a question about it before, but no one really understood my problem, so im trying a new approach to it this time.

If you're curious this is my problem:

My program takes arguments in the form of char* argv[] , and im having trouble making a pointer to whatever is on argv[1] using LPWSTR, since it only point to const wchar_t* objects.

This is a new thing im trying to solve my problem (i've tried multiple things but i need to know how to do what im thinking, or if its possible)

Basicly, my idea is to #define some sort of function that take whatever is on argv[1] and defines a const wchar_t* with that value.

Something like this:

#define path       ((const wchar_t*)argv[1])

Im not sure that is the correct way (or even if this is possible) to do what i want to do...

If you have anny better way of solving me problem, please (please) tell me how to and help me out, i've been thinking about this so a really long time!

Explanation of my program:

Im making a program that recieves arguments. The arguments are the name of the drives, for example "F:". It then uses the function CreateFile with the drive letter. If you go here , and see the first parameter of the function, i think you will see what i mean.... the problem is that for me to make a LPWSTR, i would need a const wchat_t* object.... I hope my question is clear this time, last time people didnt really understand what i was trying to do.

Regardless, thanks! EDIT 1: here are solve lines of my program (this is how i have to do for it to work, without arguments) (i used a fixed value in here)

int main()
{

HANDLE device;

device = CreateFile(L"\\\\.\\F:",    // Drive to open
    GENERIC_READ | GENERIC_WRITE,       // Access mode
    FILE_SHARE_READ | FILE_SHARE_WRITE, // Share Mode
    NULL,                   // Security Descriptor
    OPEN_EXISTING,          // How to create
    0,                      // File attributes
    NULL);  
}

This is with arguments (doesn't work)

int main(int argc, char* argv[])
{

HANDLE device;

device = CreateFile(argv[1],    // Drive to open
    GENERIC_READ | GENERIC_WRITE,       // Access mode
    FILE_SHARE_READ | FILE_SHARE_WRITE, // Share Mode
    NULL,                   // Security Descriptor
    OPEN_EXISTING,          // How to create
    0,                      // File attributes
    NULL);                  // Handle to template
}

^ this shows what im trying to do

EDIT 2: i changed the CreateFile to CreateFileA , and this is the eroor codes it gives me (the drive D is a usb, its not a hard drive) erros

So unless im typing the wrong way to type a path, it always gives me erros. I think ill try another way to solve the problem, or if someone knows why thoes errors are happening, please tell!


Solution

  • EDIT 2: i changed the CreateFile to CreateFileA , and this is the eroor codes it gives me (the drive D is a usb, its not a hard drive)

    This is a completely different question, and has nothing to do with wchar_t.

    In your first snipped you passed "\\\\.\\F:" (AKA \\.\F: once we remove the C escaping); in all your tries from the command line you never provided this path, but respectively:

    To open a drive as a device, you must use the \\.\X: path (where X is the drive letter); you cannot just throw whatever floats in your mind and hope that it'll work. Call your program from the command line passing "\\.\D:" and it'll work fine.

    Of course if you want to keep it simpler for the user you can accept just the drive letter on the command line and write some code to create the string required by CreateFile based on it.

    if(argc<1) {
        printf("Not enough arguments\n");
        return 1;
    }
    const char *drive = argv[1];
    char d = drive[0];
    // accept both `d` and `d:` as argument for the drive
    if(!((d>='a' && d<='z') || (d>='A' && d<='Z')) ||
         (drive[1]!=0 && drive[1]!=':') ||
          drive[2]!=0) {
        printf("Invalid drive specifier: `%s`\n", drive);
        return 2;
    }
    char path[]="\\\\.\\X:";
    path[4] = d;
    // now you can use path as argument to CreateFileA
    

    What follows was the original answer, which is still valid but it addresses a completely different problem, unrelated to the actual problem OP is experiencing

    You cannot make LPWSTR point to a char *, especially not by brutally casting the pointer - casting a pointer just makes the compiler shut up, it doesn't change the fact that what you are pointing at is not a wchar_t string. If you want to pass a char * to a function expecting a wchar_t * you have to perform an actual conversion of the pointed data.

    Now, you have several possible solutions:

    The last two solutions are not great because using local-encoding strings as command line arguments precludes your program from opening files using arbitrary Unicode characters. OTOH, using wchar_t almost everywhere is quite a dread, since they "infect" virtually every string-processing corner of your application. The correct (IMHO) way out is to use UTF-8 everywhere, and convert on the fly when talking to the operating systems; see here for details.