66
77#include <Python.h>
88#include <windows.h>
9- #include <tchar.h>
109
1110#include "../../arch/all/init.h"
1211
@@ -221,21 +220,25 @@ psutil_disk_io_counters(PyObject *self, PyObject *args) {
221220
222221PyObject *
223222psutil_disk_partitions (PyObject * self , PyObject * args ) {
224- DWORD num_bytes ;
225- char drive_strings [255 ];
226- char * drive_letter = drive_strings ;
227- char mp_buf [MAX_PATH ];
228- char mp_path [MAX_PATH ];
223+ DWORD num_chars ;
224+ wchar_t drive_strings [255 ];
225+ wchar_t * drive_letter = drive_strings ;
226+ wchar_t mp_buf [MAX_PATH ];
227+ wchar_t mp_path [MAX_PATH ];
229228 int all = 0 ;
230229 int type ;
231230 int ret ;
232231 unsigned int old_mode = 0 ;
233232 char opts [50 ];
234233 HANDLE mp_h ;
235234 BOOL mp_flag = TRUE;
236- char fs_type [MAX_PATH + 1 ] = {0 };
235+ wchar_t fs_type [MAX_PATH + 1 ] = {0 };
237236 DWORD pflags = 0 ;
238237 DWORD lpMaximumComponentLength = 0 ; // max file name
238+ PyObject * py_drive = NULL ;
239+ PyObject * py_mount = NULL ;
240+ PyObject * py_fs = NULL ;
241+ PyObject * py_opts = NULL ;
239242 PyObject * py_retlist = PyList_New (0 );
240243
241244 if (py_retlist == NULL ) {
@@ -250,11 +253,11 @@ psutil_disk_partitions(PyObject *self, PyObject *args) {
250253 goto error ;
251254
252255 Py_BEGIN_ALLOW_THREADS
253- num_bytes = GetLogicalDriveStrings (254 , drive_letter );
256+ num_chars = GetLogicalDriveStringsW (254 , drive_letter );
254257 Py_END_ALLOW_THREADS
255258
256- if (num_bytes == 0 ) {
257- psutil_oserror ( );
259+ if (num_chars == 0 ) {
260+ psutil_oserror_wsyscall ( "GetLogicalDriveStringsW" );
258261 goto error ;
259262 }
260263
@@ -263,7 +266,7 @@ psutil_disk_partitions(PyObject *self, PyObject *args) {
263266 fs_type [0 ] = 0 ;
264267
265268 Py_BEGIN_ALLOW_THREADS
266- type = GetDriveType (drive_letter );
269+ type = GetDriveTypeW (drive_letter );
267270 Py_END_ALLOW_THREADS
268271
269272 // by default we only show hard drives and cd-roms
@@ -276,7 +279,7 @@ psutil_disk_partitions(PyObject *self, PyObject *args) {
276279 // floppy disk: skip it by default as it introduces a
277280 // considerable slowdown.
278281 if ((type == DRIVE_REMOVABLE )
279- && (strcmp (drive_letter , "A:\\" ) == 0 ))
282+ && (wcscmp (drive_letter , L "A:\\" ) == 0 ))
280283 {
281284 goto next ;
282285 }
@@ -285,8 +288,8 @@ psutil_disk_partitions(PyObject *self, PyObject *args) {
285288 // May spin up a removable drive or go over the wire for a
286289 // network one, so do it without the GIL.
287290 Py_BEGIN_ALLOW_THREADS
288- ret = GetVolumeInformation (
289- ( LPCTSTR ) drive_letter ,
291+ ret = GetVolumeInformationW (
292+ drive_letter ,
290293 NULL , // we don't want the volume name
291294 0 ,
292295 NULL ,
@@ -320,40 +323,64 @@ psutil_disk_partitions(PyObject *self, PyObject *args) {
320323 str_append (opts , sizeof (opts ), "," );
321324 str_append (opts , sizeof (opts ), psutil_get_drive_type (type ));
322325
326+ // Convert the strings which will go into the result tuples.
327+ py_drive = PyUnicode_FromWideChar (drive_letter , wcslen (drive_letter ));
328+ if (py_drive == NULL )
329+ goto error ;
330+ py_fs = PyUnicode_FromWideChar (fs_type , wcslen (fs_type ));
331+ if (py_fs == NULL )
332+ goto error ;
333+ // opts holds pure ASCII, so plain UTF-8 decoding is safe.
334+ py_opts = PyUnicode_FromString (opts );
335+ if (py_opts == NULL )
336+ goto error ;
337+
323338 // Check for mount points on this volume and add/get info
324339 // (checks first to know if we can even have mount points)
325340 if ((ret != 0 ) && (pflags & FILE_SUPPORTS_REPARSE_POINTS )) {
326341 Py_BEGIN_ALLOW_THREADS
327- mp_h = FindFirstVolumeMountPoint (drive_letter , mp_buf , MAX_PATH );
342+ mp_h = FindFirstVolumeMountPointW (drive_letter , mp_buf , MAX_PATH );
328343 Py_END_ALLOW_THREADS
329344
330345 if (mp_h != INVALID_HANDLE_VALUE ) {
331346 mp_flag = TRUE;
332347 while (mp_flag ) {
333- // Append full mount path with drive letter
334- str_copy (
335- mp_path , sizeof (mp_path ), drive_letter
336- ); // initialize
337- str_append (
338- mp_path , sizeof (mp_path ), mp_buf
339- ); // append mount point
348+ // Append full mount path with drive letter.
349+ mp_path [0 ] = L'\0' ;
350+ wcsncat (mp_path , drive_letter , _ARRAYSIZE (mp_path ) - 1 );
351+ wcsncat (
352+ mp_path ,
353+ mp_buf ,
354+ _ARRAYSIZE (mp_path ) - wcslen (mp_path ) - 1
355+ );
356+
357+ py_mount = PyUnicode_FromWideChar (
358+ mp_path , wcslen (mp_path )
359+ );
360+ if (py_mount == NULL ) {
361+ FindVolumeMountPointClose (mp_h );
362+ goto error ;
363+ }
340364
341365 if (!pylist_append_fmt (
342366 py_retlist ,
343- "(ssss )" ,
344- drive_letter ,
345- mp_path ,
346- fs_type , // typically "NTFS"
347- opts
367+ "(OOOO )" ,
368+ py_drive ,
369+ py_mount ,
370+ py_fs , // typically "NTFS"
371+ py_opts
348372 ))
349373 {
350374 FindVolumeMountPointClose (mp_h );
351375 goto error ;
352376 }
377+ Py_CLEAR (py_mount );
353378
354379 // Continue looking for more mount points
355380 Py_BEGIN_ALLOW_THREADS
356- mp_flag = FindNextVolumeMountPoint (mp_h , mp_buf , MAX_PATH );
381+ mp_flag = FindNextVolumeMountPointW (
382+ mp_h , mp_buf , MAX_PATH
383+ );
357384 Py_END_ALLOW_THREADS
358385 }
359386 FindVolumeMountPointClose (mp_h );
@@ -362,25 +389,33 @@ psutil_disk_partitions(PyObject *self, PyObject *args) {
362389
363390 if (!pylist_append_fmt (
364391 py_retlist ,
365- "(ssss )" ,
366- drive_letter ,
367- drive_letter ,
368- fs_type , // either FAT, FAT32, NTFS, HPFS, CDFS, UDF or NWFS
369- opts
392+ "(OOOO )" ,
393+ py_drive ,
394+ py_drive ,
395+ py_fs , // either FAT, FAT32, NTFS, HPFS, CDFS, UDF or NWFS
396+ py_opts
370397 ))
371398 {
372399 goto error ;
373400 }
374401 goto next ;
375402
376403 next :
377- drive_letter = strchr (drive_letter , 0 ) + 1 ;
404+ Py_CLEAR (py_opts );
405+ Py_CLEAR (py_fs );
406+ Py_CLEAR (py_mount );
407+ Py_CLEAR (py_drive );
408+ drive_letter = wcschr (drive_letter , 0 ) + 1 ;
378409 }
379410
380411 SetErrorMode (old_mode );
381412 return py_retlist ;
382413
383414error :
415+ Py_XDECREF (py_opts );
416+ Py_XDECREF (py_fs );
417+ Py_XDECREF (py_mount );
418+ Py_XDECREF (py_drive );
384419 SetErrorMode (old_mode );
385420 Py_DECREF (py_retlist );
386421 return NULL ;
@@ -392,23 +427,32 @@ psutil_disk_partitions(PyObject *self, PyObject *args) {
392427// If no match is found return an empty string.
393428PyObject *
394429psutil_QueryDosDevice (PyObject * self , PyObject * args ) {
395- LPCTSTR lpDevicePath ;
396- TCHAR d = TEXT ('A' );
397- TCHAR szBuff [5 ];
430+ PyObject * py_device_path ;
431+ PyObject * py_ret = NULL ;
432+ wchar_t * device_path ;
433+ wchar_t d = L'A' ;
398434
399- if (!PyArg_ParseTuple (args , "s " , & lpDevicePath ))
435+ if (!PyArg_ParseTuple (args , "U " , & py_device_path ))
400436 return NULL ;
401437
402- while (d <= TEXT ('Z' )) {
403- TCHAR szDeviceName [3 ] = {d , TEXT (':' ), TEXT ('\0' )};
404- TCHAR szTarget [512 ] = {0 };
405- if (QueryDosDevice (szDeviceName , szTarget , 511 ) != 0 ) {
406- if (_tcscmp (lpDevicePath , szTarget ) == 0 ) {
407- _stprintf_s (szBuff , _countof (szBuff ), TEXT ("%c:" ), d );
408- return PyUnicode_FromString (szBuff );
438+ device_path = PyUnicode_AsWideCharString (py_device_path , NULL );
439+ if (device_path == NULL )
440+ return NULL ;
441+
442+ while (d <= L'Z' ) {
443+ wchar_t szDeviceName [3 ] = {d , L':' , L'\0' };
444+ wchar_t szTarget [512 ] = {0 };
445+ if (QueryDosDeviceW (szDeviceName , szTarget , 511 ) != 0 ) {
446+ if (wcscmp (device_path , szTarget ) == 0 ) {
447+ py_ret = PyUnicode_FromWideChar (
448+ szDeviceName , wcslen (szDeviceName )
449+ );
450+ PyMem_Free (device_path );
451+ return py_ret ;
409452 }
410453 }
411454 d ++ ;
412455 }
456+ PyMem_Free (device_path );
413457 return PyUnicode_FromString ("" );
414458}
0 commit comments