Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 4637
  • Last Modified:

LPCTSTR in C#

Hello.

        I am making an application where I am including two projects in one. First is a managed C++ dll creator and the second is a c# test application using the above as a reference.
        The problem is that I am using a function which has arguments as LPCTSTR in managed c++ but when I try to pass arguments to this function from c# (which I pass as string) I get an error : cannot convert from 'string' to 'sbyte*'.
               
In Managed C++
      DWORD LoadDriver(LPCTSTR name, LPCTSTR path, LPCTSTR dosName, bool start);
In c#
       filterDriver.LoadDriver("driver.sys","\\c:\windows\\system32", null, true);

Kindly help.
Thanks.
0
amidya
Asked:
amidya
2 Solutions
 
AlexFMCommented:
LPCTSTR is unmanaged pointer. To convert managed string to unmanaged pointer you need to use Marshal.StringToHGlobalAnsi or Marshal.StringToHGlobalUni Methods:

String s1 = "driver.sys";
String s2 = "\\c:\windows\\system32";

IntPtr p1 = Marshal.StringToHGlobalAnsi(s1);
IntPtr p2 = Marshal.StringToHGlobalAnsi(s2);

filterDriver.LoadDriverp1,p2, IntPtr.Zero, true);

Marshal.FreeCoTaskMem(p1);
Marshal.FreeCoTaskMem(p2);

Replace StringToHGlobalAnsi to StringToHGlobalUni if C++ application is UNICODE.
By the way, if you want to use LoadDriver function from C#, make it's interface pure managed: (String, String, String, int)



0
 
ptmcompCommented:
Are you programming unmanaged C#? You can avoid unmanaged C# and use attributes (MarshalAs) to define how managed types are marshalled.
0
 
OwnasaurusCommented:
Also, do u mean "\\c:\\windows\\system32" instead of "\\c:\windows\\system32"?
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
amidyaAuthor Commented:
This is with reference to the answer posted by Mr. Alex.

Sir, I am getting an error msg:

cannot convert from 'System.IntPtr' to 'sbyte*'

Please clarify.

Thanks.
0
 
amidyaAuthor Commented:
THE FOLLOWING IS MY C++ .DLL PROJECT BEING USED BY A C# APPLICATION

namespace mydriver
{
      public __gc class TDriver
      {
            private:
                  HANDLE driverHandle;      //driver handle
                  LPTSTR driverName;            //driver name
                  LPTSTR driverPath;            //driver disk path
                  LPTSTR driverDosName;      //driver's dos name, to link with it
                  bool initialized;      //variables to store the status of this class
                  bool started;
                  bool loaded;
                  bool removable;
                  //get a handle to the driver
                  DWORD OpenDevice(void);      
            
            public:
                  TDriver();
                  ~TDriver();
                  //functions to initialized the driver variables
                  DWORD InitDriver(LPCTSTR name, LPCTSTR path, LPCTSTR dosName);
                  DWORD InitDriver(LPCTSTR path);

                  //functions to load and unload drivers. If start = TRUE, the driver will be started.
                  DWORD LoadDriver(bool start);
                  //DWORD LoadDriver(LPCTSTR name, LPCTSTR path, LPCTSTR dosName, bool start);
                  DWORD LoadDriver(LPCTSTR name, LPCTSTR path, LPCTSTR dosName, bool start);

                  DWORD LoadDriver(LPCTSTR path, bool start);

                  //if forceClearData == TRUE, will remove variables although we cant remove driver "service"
                  DWORD UnloadDriver(bool forceClearData);
      
                  //functions to start and stop, driver "service"
                  DWORD StartDriver();
                  DWORD StopDriver();

                  bool IsStarted();
                  bool IsLoaded();
                  bool IsInitialized();
                  void SetRemovable(bool value);

                  //funtions to make IO operation with driver
                  DWORD WriteIo(DWORD code, PVOID buffer, DWORD count);
                  DWORD ReadIo(DWORD code, PVOID buffer, DWORD count);
                  DWORD RawIo(DWORD code, PVOID inBuffer, DWORD inCount, PVOID outBuffer, DWORD outCount);

                  //function to get driver handle
                  HANDLE GetDriverHandle(void);
      
      };

      TDriver::TDriver()            //constructor
      {
            //Constructor. Initialize variables.
            driverHandle = NULL;
            removable = true;
            driverName = NULL;
            driverPath = NULL;
            driverDosName = NULL;
            initialized = false;
            loaded = false;
            started = false;
      }
                  
      TDriver::~TDriver()            //destructor
      {
            if(driverHandle != NULL)
            {
                  CloseHandle(driverHandle);
                  driverHandle = NULL;
            }
          UnloadDriver(false);
      }

      //if true, the driver havent been removed at finish
      void TDriver::SetRemovable(bool value)
      {
            removable = value;
      }

      //funtion to return class status
      bool TDriver::IsInitialized()
      {
            return initialized;
      }

      //is driver loaded?
      bool TDriver::IsLoaded(void)
      {
            return loaded;
      }

      //is driver started?
      bool TDriver::IsStarted(void)
      {
            return started;
      }

//Init the driver class variables
DWORD TDriver::InitDriver(LPCTSTR path)
{
      //if already initialized, first unload
      if(initialized)
      {
            if(UnloadDriver(false) != DRV_SUCCESS)
                  return DRV_ERROR_ALREADY_INITIALIZED;
      }

      //if yes, i analized the path to extract driver name
      driverPath = (LPTSTR)malloc(strlen(path) + 1);

      if(driverPath == NULL)
            return DRV_ERROR_MEMORY;

      strcpy(driverPath, path);


      //first i search the last backslash
      LPTSTR sPos1 = strrchr(driverPath, (int)'\\');

      //if NULL, the string havent any backslash
      if (sPos1 == NULL)
            sPos1 = driverPath;


      //now, i search .sys
      LPTSTR sPos2 = strrchr(sPos1, (int)'.');

      if (sPos2 == NULL || sPos1 > sPos2)
      {
            free(driverPath);
            driverPath = NULL;

            return DRV_ERROR_INVALID_PATH_OR_FILE;
      }
      
      //extract the driver name
      driverName = (LPTSTR) malloc (sPos2 - sPos1);
      
      if(driverName == NULL)
      {
            free(driverPath);
            driverPath = NULL;

            return DRV_ERROR_MEMORY;
      }

      memcpy(driverName, sPos1 + 1, sPos2 - sPos1 - 1);
      
      driverName[sPos2 - sPos1 - 1] = 0;

      //driverDosName = \\.\driverName
      driverDosName = (LPTSTR) malloc (strlen(driverName) + 5);

      if(driverDosName == NULL)
      {
            free(driverPath);
            driverPath = NULL;

            free(driverName);
            driverName = NULL;

            return DRV_ERROR_MEMORY;
      }

      sprintf(driverDosName, "\\\\.\\%s", driverName);

            
      initialized = true;
      return DRV_SUCCESS;
}


//Init the driver class variables
DWORD TDriver::InitDriver(LPCTSTR name, LPCTSTR path, LPCTSTR dosName)
{      
      //if already initialized, first unload
      if(initialized)
      {
            if(UnloadDriver(false) != DRV_SUCCESS)
                  return DRV_ERROR_ALREADY_INITIALIZED;
      }

      LPTSTR dirBuffer;

      //if the user introduced path, first i will ckeck it
      if (path != NULL)
      {
            //if yes, copy in auxiliar buffer and continue
            DWORD len = (DWORD)(strlen(name) + strlen(path) + 1);
            dirBuffer = (LPTSTR) malloc (len);

            if(dirBuffer == NULL)
                  return DRV_ERROR_MEMORY;

            strcpy(dirBuffer, path);

      }

      else
      {
            //if the user dont introduced path, i search in curren directory
            LPTSTR pathBuffer;
        DWORD len = GetCurrentDirectory(0, NULL);
     
            pathBuffer = (LPTSTR) malloc (len);

            if(pathBuffer == NULL)
                  return DRV_ERROR_MEMORY;

                   
        if (GetCurrentDirectory(len, pathBuffer) != 0)
            {
                  len = (DWORD)(strlen(pathBuffer) + strlen(name) + 6);
                  dirBuffer = (LPTSTR) malloc (len);

                  if(dirBuffer == NULL)
                  {
                        free(pathBuffer);

                        return DRV_ERROR_MEMORY;
                  }

                  //complete de total path, currentdirectory\driverName.sys
                  sprintf(dirBuffer, "%s\\%s.sys", pathBuffer, name);

                  //exists this file?
                  if(GetFileAttributes(dirBuffer) == 0xFFFFFFFF)
                  {
                        free(pathBuffer);
                        free(dirBuffer);

                        //if no, i search in \system32\drivers\
                        LPCTSTR sysDriver = "\\system32\\Drivers\\";
                        LPTSTR sysPath;
                   
                        //i have to get the windows directory
                        DWORD len = GetWindowsDirectory(NULL, 0);
                       sysPath = (LPTSTR) malloc (len + strlen(sysDriver));

                        if(sysPath == NULL)
                              return DRV_ERROR_MEMORY;

                        if (GetWindowsDirectory(sysPath, len) == 0)
                        {
                              free(sysPath);
                              
                              return DRV_ERROR_UNKNOWN;
                        }
      
                        //complete the path and check it
                        strcat(sysPath, sysDriver);
                        len = (DWORD)(strlen(sysPath) + strlen(name) + 5);

                        dirBuffer = (LPTSTR) malloc (len);

                        if(dirBuffer == NULL)
                              return DRV_ERROR_MEMORY;

                        sprintf(dirBuffer, "%s%s.sys", sysPath, name);

                        free(sysPath);

                        //if the file neither exist, i dont know where is it -> i dont initialize
                        if(GetFileAttributes(dirBuffer) == 0xFFFFFFFF)
                        {
                              free(dirBuffer);

                              return DRV_ERROR_INVALID_PATH_OR_FILE;
                        }
                  }
        }

            else
            {
                  free(pathBuffer);

                  return DRV_ERROR_UNKNOWN;
            }
      }
      
      //Write driver's variables with obtained data
      driverPath = dirBuffer;

      driverName = (LPTSTR)malloc(strlen(name) + 1);

      if(driverName == NULL)
      {
            free(driverPath);
            driverPath = NULL;
            
            return DRV_ERROR_MEMORY;
      }

      strcpy(driverName, name);
      
      LPCTSTR auxBuffer;
      if(dosName != NULL)
        auxBuffer = dosName;
      
      else
            auxBuffer = name;

      //dosName=\\.\driverName
      if(auxBuffer[0] != '\\' && auxBuffer[1] != '\\')
      {
            driverDosName = (LPTSTR) malloc (strlen(auxBuffer) + 5);

            if(driverDosName == NULL)
            {
                  free(driverPath);
                  driverPath = NULL;

                  free(driverName);
                  driverName = NULL;

                  return DRV_ERROR_MEMORY;
            }

            sprintf(driverDosName, "\\\\.\\%s", auxBuffer);
      }

      else
      {
            driverDosName = (LPTSTR) malloc (strlen(auxBuffer));

            if(driverDosName == NULL)
            {
                  free(driverPath);
                  driverPath = NULL;

                  free(driverName);
                  driverName = NULL;

                  return DRV_ERROR_MEMORY;
            }

            strcpy(driverDosName, auxBuffer);
      }

      //set the state to initialized
      initialized = true;

      return DRV_SUCCESS;
}


//Function to Load the driver.
DWORD TDriver::LoadDriver(LPCTSTR name, LPCTSTR path, LPCTSTR dosName, bool start)
{
      //first initialized it
      DWORD retCode = InitDriver(name, path, dosName);

      //then load
      if(retCode == DRV_SUCCESS)
            retCode = LoadDriver(start);

      return retCode;
}

//Function to load the driver
DWORD TDriver::LoadDriver(LPCTSTR path, bool start)
{
      //first initialized it
      DWORD retCode = InitDriver(path);

      //then load
      if(retCode == DRV_SUCCESS)
            retCode = LoadDriver(start);

      return retCode;
}


//Function to Load the driver
DWORD TDriver::LoadDriver(bool start)
{
      //if the driver is already started, i havent to do nothing
      if(loaded)
            return DRV_SUCCESS;

      if(initialized==false)
            return DRV_ERROR_NO_INITIALIZED;

      //Open Service manager to create the new "service"
      SC_HANDLE SCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
      DWORD retCode = DRV_SUCCESS;
      
      if (SCManager == NULL)
            return DRV_ERROR_SCM;

   

    //Create the driver "service"
    SC_HANDLE  SCService = CreateService(SCManager,                    // SCManager database
                                                           driverName,            // nombre del servicio
                                                           driverName,            // nombre a mostrar
                                                             SERVICE_ALL_ACCESS,    // acceso total
                                                             SERVICE_KERNEL_DRIVER, // driver del kernel
                                                             SERVICE_DEMAND_START,  // comienzo bajo demanda
                                                             SERVICE_ERROR_NORMAL,  // control de errores normal
                                                             driverPath,                // path del driver
                                                             NULL,                  // no pertenece a un grupo
                                                             NULL,                  // sin tag
                                                             NULL,                  // sin dependencias
                                                             NULL,                  // cuenta local del sistema
                                                             NULL                   // sin password
                                                             );
   
      //if i cant create, first i check if the driver already was loaded.
      if (SCService == NULL)
      {
            SCService = OpenService(SCManager, driverName, SERVICE_ALL_ACCESS);
            
            if (SCService == NULL)
                  retCode = DRV_ERROR_SERVICE;
      }

    CloseServiceHandle(SCService);
      SCService=NULL;

      CloseServiceHandle(SCManager);
      SCManager = NULL;

      //if all ok, update the state and start if necessary
      if(retCode == DRV_SUCCESS)
      {
            loaded = true;

            if(start)
                  retCode = StartDriver();
      }

      return retCode;
}


//Function to Unload a driver
DWORD TDriver::UnloadDriver(bool forceClearData)
{
      DWORD retCode = DRV_SUCCESS;

      //if the driver is started, first i will stop it
      if (started)
      {
            if ((retCode = StopDriver()) == DRV_SUCCESS)
            {
                  //i only remove it, if it is mark to be removable
                  if(removable)
                  {
                        //open service and delete it
                        SC_HANDLE SCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
                        
                        if (SCManager == NULL)
                              return DRV_ERROR_SCM;

                        SC_HANDLE SCService = OpenService(SCManager, driverName, SERVICE_ALL_ACCESS);
                        
                        if (SCService != NULL)
                        {
                              if(!DeleteService(SCService))
                                    retCode = DRV_ERROR_REMOVING;
                              else
                                    retCode = DRV_SUCCESS;
                        }

                        else
                              retCode = DRV_ERROR_SERVICE;

                        CloseServiceHandle(SCService);
                        SCService = NULL;

                        CloseServiceHandle(SCManager);
                        SCManager = NULL;

                        //if all ok, update the state
                        if(retCode == DRV_SUCCESS)
                              loaded = false;
                  }
            }
      }

      //if the driver is initialized...
      if(initialized)
      {
            //if there was some problem but i mark foreceClear, i will remove the data
            if(retCode != DRV_SUCCESS && forceClearData == false)
                  return retCode;
            
            //update the state
            initialized = false;
                        
            //free memory
            if(driverPath != NULL)
            {
                  free(driverPath);
                  driverPath = NULL;
            }


            if(driverDosName != NULL)
            {
                  free(driverDosName);
                  driverDosName = NULL;
            }

            if(driverName != NULL)
            {
                  free(driverName);
                  driverName = NULL;
            }

      }

      return retCode;
}

//Function to start the driver "service"
DWORD TDriver::StartDriver(void)
{
      //if already started, all ok
      if(started)
            return DRV_SUCCESS;

      //open the service manager and the service and change driver state
      SC_HANDLE SCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
      DWORD retCode;
      
      if (SCManager == NULL)
            return DRV_ERROR_SCM;

    SC_HANDLE SCService = OpenService(SCManager,
                                          driverName,
                                              SERVICE_ALL_ACCESS);
   
      if (SCService == NULL)
        return DRV_ERROR_SERVICE;

   
    if (!StartService( SCService, 0, NULL))
      {
            //if the driver was started before i try to do it,
            //i will not remove, because it was created by other application
        if (GetLastError() == ERROR_SERVICE_ALREADY_RUNNING)
            {
                  removable = false;

                  retCode = DRV_SUCCESS;
            }

            else
                  retCode = DRV_ERROR_STARTING;
    }

      else
            retCode = DRV_SUCCESS;

 
    CloseServiceHandle(SCService);
      SCService = NULL;

      CloseServiceHandle(SCManager);
      SCManager = NULL;

      //update the state and open device
      if(retCode == DRV_SUCCESS)
      {
            started = true;

            retCode = OpenDevice();
      }

    return retCode;
}



//Function to stop driver "service"
DWORD TDriver::StopDriver(void)
{
      //if already stopped, all ok
      if(started==false)
            return DRV_SUCCESS;

      //open the service manager and the service and change driver state
      SC_HANDLE SCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
      DWORD retCode;
      
      if (SCManager == NULL)
            return DRV_ERROR_SCM;

   
    SERVICE_STATUS  status;

    SC_HANDLE SCService = OpenService(SCManager, driverName, SERVICE_ALL_ACCESS);
   
      if (SCService != NULL)
      {
            //close the driver handle too
            CloseHandle(driverHandle);
            driverHandle = NULL;

            if(!ControlService(SCService, SERVICE_CONTROL_STOP, &status))
                  retCode = DRV_ERROR_STOPPING;

            else
                  retCode = DRV_SUCCESS;
      }

      else
            retCode = DRV_ERROR_SERVICE;


    CloseServiceHandle(SCService);
      SCService = NULL;

      CloseServiceHandle(SCManager);
      SCManager = NULL;

      //update the state
      if(retCode == DRV_SUCCESS)
            started = false;

    return retCode;
}


//Funtion to open a driver handle
DWORD TDriver::OpenDevice(void)
{
      //if i already have a handle, first close it
      if (driverHandle != NULL)
            CloseHandle(driverHandle);

    driverHandle = CreateFile(driverDosName,
                                            GENERIC_READ | GENERIC_WRITE,
                                            0,
                              NULL,
                              OPEN_EXISTING,
                              FILE_ATTRIBUTE_NORMAL,
                              NULL);


    if(driverHandle == INVALID_HANDLE_VALUE)
            return DRV_ERROR_INVALID_HANDLE;
      
      return DRV_SUCCESS;
}


//Return the driverHandle obtained
HANDLE TDriver::GetDriverHandle(void)
{
      return driverHandle;
}


//Funtion to send data to the driver
DWORD TDriver::WriteIo(DWORD code, PVOID buffer, DWORD count)
{
      if(driverHandle == NULL)
            return DRV_ERROR_INVALID_HANDLE;

      DWORD bytesReturned;

      bool returnCode = DeviceIoControl(driverHandle,
                                                      code,
                                                      buffer,
                                                      count,
                                                      NULL,
                                                      0,
                                                      &bytesReturned,
                                                      NULL);

      if(!returnCode)
            return DRV_ERROR_IO;

      return DRV_SUCCESS;
}


//Functions to read data from the driver
DWORD TDriver::ReadIo(DWORD code, PVOID buffer, DWORD count)
{
      if(driverHandle == NULL)
            return DRV_ERROR_INVALID_HANDLE;

      DWORD bytesReturned;
      bool retCode = DeviceIoControl(driverHandle,
                                                   code,
                                                   NULL,
                                                   0,
                                                   buffer,
                                                   count,
                                                   &bytesReturned,
                                                   NULL);

      if(!retCode)
            return DRV_ERROR_IO;

      return bytesReturned;
}


//Function to do IO operation with the driver, read or write or both
DWORD TDriver::RawIo(DWORD code, PVOID inBuffer, DWORD inCount, PVOID outBuffer, DWORD outCount)
{
      if(driverHandle == NULL)
            return DRV_ERROR_INVALID_HANDLE;

      DWORD bytesReturned;
      bool retCode = DeviceIoControl(driverHandle,
                                                   code,
                                                   inBuffer,
                                                   inCount,
                                                   outBuffer,
                                                   outCount,
                                                   &bytesReturned,
                                                   NULL);

      if(!retCode)
            return DRV_ERROR_IO;

      return bytesReturned;
}
}

0
 
RomanPetrenkoCommented:
If you're working with managed c++ why do you use unmanaged types in your LoadDriver function?
use
LoadDriver(String* name, String* path, String* dosName, bool start)
and for calling non-managed code convert this strings to char* with following code:
char* szMessage = (char*)Marshal::StringToHGlobalAnsi(strMessage);
<... Unmanaged call...>
Marshal::FreeHGlobal((int)szMessage);

look here:
Mixing Managed and Unmanaged code
http://www.codeproject.com/dotnet/managed_unmanaged.asp?target=managed%7Ctypes
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now