@@ -5,52 +5,42 @@
 # and http://pywin32.hg.sourceforge.net/hgweb/pywin32/pywin32/file/4c7503da2658/win32/src/win32clipboardmodule.cpp
 
 import ctypes
-from ctypes import c_int, c_char, c_char_p, c_wchar, c_wchar_p, sizeof
+from ctypes import c_int, c_size_t, c_wchar, c_void_p, sizeof, memmove
 
-# Get required functions, strcpy..
-strcpy = ctypes.cdll.msvcrt.strcpy
-wcscpy = ctypes.cdll.msvcrt.wcscpy
+# Get required functions.
 ocb = ctypes.windll.user32.OpenClipboard  # Basic Clipboard functions
 ecb = ctypes.windll.user32.EmptyClipboard
 gcd = ctypes.windll.user32.GetClipboardData
 scd = ctypes.windll.user32.SetClipboardData
 rcf = ctypes.windll.user32.RegisterClipboardFormatA
 ccb = ctypes.windll.user32.CloseClipboard
 ga = ctypes.windll.kernel32.GlobalAlloc    # Global Memory allocation
+ga.restype = c_void_p
 gl = ctypes.windll.kernel32.GlobalLock     # Global Memory Locking
+gl.restype = c_void_p
 gul = ctypes.windll.kernel32.GlobalUnlock
+gle = ctypes.windll.kernel32.GetLastError
 GHND = 0x0042
 
-CF_HTML = rcf("HTML Format")
-CF_RTF = rcf("Rich Text Format")
-CF_RTFWO = rcf("Rich Text Format Without Objects")
+CF_HTML = rcf("HTML Format".encode())
+CF_RTF = rcf("Rich Text Format".encode())
+CF_RTFWO = rcf("Rich Text Format Without Objects".encode())
 CF_TEXT = 1
 CF_UNICODETEXT = 13
 
-
-def Get():
-    ocb(None)  # Open Clip, Default task
-    pcontents = gcd(1)  # 1 means CF_TEXT.. too lazy to get the token thingy ...
-    data = c_char_p(pcontents).value
-    #gul(pcontents) ?
-    ccb()
-
-    return data
-
-
 def Paste(data, type='text', plaintext=None):
     if plaintext is None:
         plaintext = data
 
     if type == 'html':
         data = EncodeHTML(data)
-    else:
-        data = data.encode('cp1252', 'replace')
+
+    data = data.encode('utf-8', 'replace')
 
     unicodetext = plaintext.encode('utf_16')
     plaintext = plaintext.encode('cp1252', 'replace')
 
-    ocb(None)  # Open Clip, Default task
+    ocb(c_void_p(0))  # Open Clip, Default task
     ecb()
 
     if type == 'rtf':
@@ -65,25 +55,28 @@ def Paste(data, type='text', plaintext=None):
 
 
 def Put(data, format):
-    if format == CF_UNICODETEXT:
-        hCd = ga(GHND, len(bytes(data)) + sizeof(c_char()))
-    else:
-        hCd = ga(GHND, len(bytes(data)) + sizeof(c_wchar()))
-
-    hCd = ga(GHND, len(bytes(data)) + 2)
-    pchData = gl(hCd)
-
-    if format == CF_UNICODETEXT:
-        wcscpy(c_wchar_p(pchData), bytes(data))
-    else:
-        strcpy(c_char_p(pchData), bytes(data))
-    gul(hCd)
-    scd(c_int(format), hCd, 0, False)
+    # Ensure we are using a bytes object.
+    data = bytes(data)
+    # Allocate global memory, including space for terminator.
+    # GHND is GMEM_MOVEABLE (required) and GMEM_ZEROINIT (convenient).
+    hCd = ga(c_int(GHND), len(data) + sizeof(c_wchar()))
+
+    # Lock the memory and get a pointer to it.
+    pchData = gl(c_void_p(hCd))
+    if not pchData:
+        code = gle()
+        raise Exception('Failed to lock: %r' % code)
+
+    # Move data into global memory.
+    memmove(c_void_p(pchData), data, c_size_t(len(data)))
+    # Unlock.
+    gul(c_void_p(hCd))
+    # Set clipboard data.
+    scd(c_int(format), c_void_p(hCd))
 
 
 # Based off of http://code.activestate.com/recipes/474121-getting-html-from-the-windows-clipboard/
 def EncodeHTML(fragment):
-    fragment = fragment.encode('utf-8', 'replace')
     DEFAULT_HTML_BODY = \
         "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">" \
         "<HTML><HEAD></HEAD><BODY><!--StartFragment-->%s<!--EndFragment--></BODY></HTML>"
