1010from ctypes .wintypes import (
1111 BOOL , DWORD , FILETIME , LPCWSTR )
1212
13- from win32ctypes .core .compat import is_text
1413from ._common import LPBYTE , _PyBytes_FromStringAndSize
1514from ._util import function_factory , check_zero_factory , dlls
16- from ._nl_support import _GetACP
17-
18-
19- SUPPORTED_CREDKEYS = set ((
20- u'Type' , u'TargetName' , u'Persist' ,
21- u'UserName' , u'Comment' , u'CredentialBlob' ))
2215
2316
2417class CREDENTIAL (Structure ):
@@ -31,68 +24,58 @@ class CREDENTIAL(Structure):
3124 ("CredentialBlobSize" , DWORD ),
3225 ("CredentialBlob" , LPBYTE ),
3326 ("Persist" , DWORD ),
34- ("_DO_NOT_USE_AttributeCount " , DWORD ),
35- ("__DO_NOT_USE_Attribute " , c_void_p ),
27+ ("AttributeCount " , DWORD ),
28+ ("Attribute " , c_void_p ),
3629 ("TargetAlias" , c_wchar_p ),
3730 ("UserName" , c_wchar_p )]
3831
3932 @classmethod
40- def fromdict (cls , credential , flags = 0 ):
41- unsupported = set (credential .keys ()) - SUPPORTED_CREDKEYS
42- if len (unsupported ):
43- raise ValueError ("Unsupported keys: {0}" .format (unsupported ))
44- if flags != 0 :
45- raise ValueError ("flag != 0 not yet supported" )
46-
33+ def fromdict (cls , credential ):
4734 c_creds = cls ()
4835 c_pcreds = PCREDENTIAL (c_creds )
4936
5037 # zero-out memory
5138 ctypes .memset (c_pcreds , 0 , ctypes .sizeof (c_creds ))
5239
53- for key in SUPPORTED_CREDKEYS :
54- if key in credential :
55- if key != 'CredentialBlob' :
56- setattr (c_creds , key , credential [key ])
57- else :
58- blob = make_unicode (credential ['CredentialBlob' ])
59- blob_data = ctypes .create_unicode_buffer (blob )
60- # Create_unicode_buffer adds a NULL at the end of the
61- # string we do not want that.
62- c_creds .CredentialBlobSize = \
63- ctypes .sizeof (blob_data ) - \
64- ctypes .sizeof (ctypes .c_wchar )
65- c_creds .CredentialBlob = ctypes .cast (blob_data , LPBYTE )
40+ for key in credential :
41+ if key == 'CredentialBlob' :
42+ blob_data , blob_size = _make_blob (credential ['CredentialBlob' ])
43+ c_creds .CredentialBlob = ctypes .cast (blob_data , LPBYTE )
44+ c_creds .CredentialBlobSize = blob_size
45+ else :
46+ setattr (c_creds , key , credential [key ])
6647 return c_creds
6748
6849
6950PCREDENTIAL = POINTER (CREDENTIAL )
7051
7152
72- def make_unicode (password ):
73- """ Convert the input string to unicode.
74-
75- """
76- if is_text (password ):
77- return password
78- else :
79- code_page = _GetACP ()
80- return password .decode (encoding = str (code_page ), errors = 'strict' )
81-
82-
8353def credential2dict (creds ):
8454 credential = {}
85- for key in SUPPORTED_CREDKEYS :
86- if key != u'CredentialBlob' :
87- credential [key ] = getattr (creds , key )
88- else :
55+ for key , type_ in CREDENTIAL ._fields_ :
56+ if key == u'CredentialBlob' :
8957 blob = _PyBytes_FromStringAndSize (
9058 cast (creds .CredentialBlob , c_char_p ),
9159 creds .CredentialBlobSize )
9260 credential [u'CredentialBlob' ] = blob
61+ else :
62+ credential [key ] = getattr (creds , key )
9363 return credential
9464
9565
66+ def _make_blob (data ):
67+ """ Convert a string to credential compatible blob dict values
68+
69+ """
70+ blob_data = ctypes .create_unicode_buffer (data )
71+ # Create_unicode_buffer adds a NULL at the end of the
72+ # string we do not want that.
73+ blob_size = (
74+ ctypes .sizeof (blob_data ) - ctypes .sizeof (ctypes .c_wchar ))
75+ blob_pointer = ctypes .cast (blob_data , LPBYTE )
76+ return blob_pointer , blob_size
77+
78+
9679_CredWrite = function_factory (
9780 dlls .advapi32 .CredWriteW ,
9881 [PCREDENTIAL , DWORD ],
0 commit comments