def _advapi32_sign(private_key, data, hash_algorithm, rsa_pss_padding=False):
algo = private_key.algorithm<EOL>if algo == '<STR_LIT>' and hash_algorithm == '<STR_LIT>':<EOL><INDENT>padded_data = add_pkcs1v15_signature_padding(private_key.byte_size, data)<EOL>return raw_rsa_private_crypt(private_key, padded_data)<EOL><DEDENT>if algo == '<STR_LIT>' and rsa_pss_padding:<EOL><INDENT>hash_length = {<EOL>'<STR_LIT>': <NUM_LIT:20>,<EOL>'<STR_LIT>': <NUM_LIT>,<EOL>'<STR_LIT>': <NUM_LIT:32>,<EOL>'<STR_LIT>': <NUM_LIT>,<EOL>'<STR_LIT>': <NUM_LIT:64><EOL>}.get(hash_algorithm, <NUM_LIT:0>)<EOL>padded_data = add_pss_padding(hash_algorithm, hash_length, private_key.bit_size, data)<EOL>return raw_rsa_private_crypt(private_key, padded_data)<EOL><DEDENT>if private_key.algorithm == '<STR_LIT>' and hash_algorithm == '<STR_LIT>':<EOL><INDENT>raise ValueError(pretty_message(<EOL>'''<STR_LIT>'''<EOL>))<EOL><DEDENT>hash_handle = None<EOL>try:<EOL><INDENT>alg_id = {<EOL>'<STR_LIT>': Advapi32Const.CALG_MD5,<EOL>'<STR_LIT>': Advapi32Const.CALG_SHA1,<EOL>'<STR_LIT>': Advapi32Const.CALG_SHA_256,<EOL>'<STR_LIT>': Advapi32Const.CALG_SHA_384,<EOL>'<STR_LIT>': Advapi32Const.CALG_SHA_512,<EOL>}[hash_algorithm]<EOL>hash_handle_pointer = new(advapi32, '<STR_LIT>')<EOL>res = advapi32.CryptCreateHash(<EOL>private_key.context_handle,<EOL>alg_id,<EOL>null(),<EOL><NUM_LIT:0>,<EOL>hash_handle_pointer<EOL>)<EOL>handle_error(res)<EOL>hash_handle = unwrap(hash_handle_pointer)<EOL>res = advapi32.CryptHashData(hash_handle, data, len(data), <NUM_LIT:0>)<EOL>handle_error(res)<EOL>out_len = new(advapi32, '<STR_LIT>')<EOL>res = advapi32.CryptSignHashW(<EOL>hash_handle,<EOL>Advapi32Const.AT_SIGNATURE,<EOL>null(),<EOL><NUM_LIT:0>,<EOL>null(),<EOL>out_len<EOL>)<EOL>handle_error(res)<EOL>buffer_length = deref(out_len)<EOL>buffer_ = buffer_from_bytes(buffer_length)<EOL>res = advapi32.CryptSignHashW(<EOL>hash_handle,<EOL>Advapi32Const.AT_SIGNATURE,<EOL>null(),<EOL><NUM_LIT:0>,<EOL>buffer_,<EOL>out_len<EOL>)<EOL>handle_error(res)<EOL>output = bytes_from_buffer(buffer_, deref(out_len))<EOL>output = output[::-<NUM_LIT:1>]<EOL>if algo == '<STR_LIT>':<EOL><INDENT>half_len = len(output) // <NUM_LIT:2><EOL>output = output[half_len:] + output[:half_len]<EOL>output = algos.DSASignature.from_p1363(output).dump()<EOL><DEDENT>return output<EOL><DEDENT>finally:<EOL><INDENT>if hash_handle:<EOL><INDENT>advapi32.CryptDestroyHash(hash_handle)<EOL><DEDENT><DEDENT>
Generates an RSA, DSA or ECDSA signature via CryptoAPI

:param private_key:
    The PrivateKey to generate the signature with

:param data:
    A byte string of the data the signature is for

:param hash_algorithm:
    A unicode string of "md5", "sha1", "sha256", "sha384", "sha512" or "raw"

:param rsa_pss_padding:
    If PSS padding should be used for RSA keys

:raises:
    ValueError - when any of the parameters contain an invalid value
    TypeError - when any of the parameters are of the wrong type
    OSError - when an error is returned by the OS crypto library

:return:
    A byte string of the signature