From ec4974e7660776e8ab2883b109bfa3f96b4f5317 Mon Sep 17 00:00:00 2001
From: "Kali Kaneko (leap communications)" <kali@leap.se>
Date: Fri, 16 Aug 2019 12:55:10 +0200
Subject: [PATCH] [pkg] need to vendorize allendang w32 lib

we use go mod edit -replace
---
 go.mod                                   |   31 +-
 go.sum                                   |   37 +-
 packages/w32/AUTHORS                     |   19 +
 packages/w32/LICENSE                     |   23 +
 packages/w32/README.md                   |   33 +
 packages/w32/advapi32.go                 |  389 ++++
 packages/w32/advapi32_constants.go       |  300 +++
 packages/w32/advapi32_typedef.go         |  122 +
 packages/w32/alpc.go                     |  304 +++
 packages/w32/alpc_constants.go           |   64 +
 packages/w32/alpc_typedef.go             |  181 ++
 packages/w32/comctl32.go                 |  109 +
 packages/w32/comdlg32.go                 |   38 +
 packages/w32/constants.go                | 2628 ++++++++++++++++++++++
 packages/w32/create_process.go           |  152 ++
 packages/w32/create_process_constants.go |    9 +
 packages/w32/create_process_typedef.go   |   68 +
 packages/w32/dwmapi.go                   |  254 +++
 packages/w32/fork.go                     |  174 ++
 packages/w32/fork_constants.go           |   26 +
 packages/w32/fork_typedef.go             |   89 +
 packages/w32/gdi32.go                    |  543 +++++
 packages/w32/gdiplus.go                  |  175 ++
 packages/w32/go.mod                      |    1 +
 packages/w32/idispatch.go                |   43 +
 packages/w32/istream.go                  |   31 +
 packages/w32/iunknown.go                 |   27 +
 packages/w32/kernel32.go                 |  388 ++++
 packages/w32/ole32.go                    |   63 +
 packages/w32/oleaut32.go                 |   48 +
 packages/w32/opengl32.go                 |   72 +
 packages/w32/psapi.go                    |   25 +
 packages/w32/shell32.go                  |  153 ++
 packages/w32/typedef.go                  |  891 ++++++++
 packages/w32/user32.go                   | 1046 +++++++++
 packages/w32/utils.go                    |  201 ++
 packages/w32/vars.go                     |   13 +
 37 files changed, 8742 insertions(+), 28 deletions(-)
 create mode 100644 packages/w32/AUTHORS
 create mode 100644 packages/w32/LICENSE
 create mode 100644 packages/w32/README.md
 create mode 100644 packages/w32/advapi32.go
 create mode 100644 packages/w32/advapi32_constants.go
 create mode 100644 packages/w32/advapi32_typedef.go
 create mode 100644 packages/w32/alpc.go
 create mode 100644 packages/w32/alpc_constants.go
 create mode 100644 packages/w32/alpc_typedef.go
 create mode 100644 packages/w32/comctl32.go
 create mode 100644 packages/w32/comdlg32.go
 create mode 100644 packages/w32/constants.go
 create mode 100644 packages/w32/create_process.go
 create mode 100644 packages/w32/create_process_constants.go
 create mode 100644 packages/w32/create_process_typedef.go
 create mode 100644 packages/w32/dwmapi.go
 create mode 100644 packages/w32/fork.go
 create mode 100644 packages/w32/fork_constants.go
 create mode 100644 packages/w32/fork_typedef.go
 create mode 100644 packages/w32/gdi32.go
 create mode 100644 packages/w32/gdiplus.go
 create mode 100644 packages/w32/go.mod
 create mode 100644 packages/w32/idispatch.go
 create mode 100644 packages/w32/istream.go
 create mode 100644 packages/w32/iunknown.go
 create mode 100644 packages/w32/kernel32.go
 create mode 100644 packages/w32/ole32.go
 create mode 100644 packages/w32/oleaut32.go
 create mode 100644 packages/w32/opengl32.go
 create mode 100644 packages/w32/psapi.go
 create mode 100644 packages/w32/shell32.go
 create mode 100644 packages/w32/typedef.go
 create mode 100644 packages/w32/user32.go
 create mode 100644 packages/w32/utils.go
 create mode 100644 packages/w32/vars.go

diff --git a/go.mod b/go.mod
index 5817b661..3e067523 100644
--- a/go.mod
+++ b/go.mod
@@ -2,28 +2,29 @@ module 0xacab.org/leap/bitmask-vpn
 
 require (
 	0xacab.org/leap/go-dialog v0.0.0-20181123042829-0ee8438431a0
-	github.com/AllenDang/w32 v0.0.0-20180428130237-ad0a36d80adc
+	github.com/AllenDang/w32 v0.0.0-20180428130237-ad0a36d80adc // indirect
 	github.com/ProtonMail/go-autostart v0.0.0-20181114175602-c5272053443a
 	github.com/apparentlymart/go-openvpn-mgmt v0.0.0-20161009010951-9a305aecd7f2
-	github.com/cratonica/2goarray v0.0.0-20190331194516-514510793eaa // indirect
-	github.com/getlantern/context v0.0.0-20190109183933-c447772a6520
-	github.com/getlantern/errors v0.0.0-20180829142810-e24b7f4ff7c7
-	github.com/getlantern/golog v0.0.0-20170508214112-cca714f7feb5
-	github.com/getlantern/hex v0.0.0-20160523043825-083fba3033ad
-	github.com/getlantern/hidden v0.0.0-20160523043807-d52a649ab33a
-	github.com/getlantern/ops v0.0.0-20170904182230-37353306c908
+	github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 // indirect
+	github.com/getlantern/errors v0.0.0-20180829142810-e24b7f4ff7c7 // indirect
+	github.com/getlantern/golog v0.0.0-20170508214112-cca714f7feb5 // indirect
+	github.com/getlantern/hex v0.0.0-20160523043825-083fba3033ad // indirect
+	github.com/getlantern/hidden v0.0.0-20160523043807-d52a649ab33a // indirect
+	github.com/getlantern/ops v0.0.0-20170904182230-37353306c908 // indirect
 	github.com/getlantern/systray v0.0.0-20190626064521-f2fa635d0474
-	github.com/go-stack/stack v1.8.0
-	github.com/golang/text v0.3.0 // indirect
-	github.com/gotk3/gotk3 v0.0.0-20190108052711-d09d58ef3476
+	github.com/go-stack/stack v1.8.0 // indirect
+	github.com/gotk3/gotk3 v0.0.0-20190108052711-d09d58ef3476 // indirect
 	github.com/jmshal/go-locale v0.0.0-20161107082030-4f541412d67a
+	github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 // indirect
 	github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936
-	github.com/oxtoacart/bpool v0.0.0-20150712133111-4e1c5567d7c2
-	github.com/sevlyar/go-daemon v0.1.5 // indirect
+	github.com/oxtoacart/bpool v0.0.0-20150712133111-4e1c5567d7c2 // indirect
+	github.com/sevlyar/go-daemon v0.1.5
 	github.com/skratchdot/open-golang v0.0.0-20190104022628-a2dfa6d0dab6
-	golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 // indirect
-	golang.org/x/net v0.0.0-20190724013045-ca1201d0de80 // indirect
+	github.com/sqweek/dialog v0.0.0-20190728103509-6254ed5b0d3c // indirect
+	github.com/stretchr/testify v1.4.0 // indirect
 	golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa // indirect
 	golang.org/x/text v0.3.2
 	golang.org/x/tools v0.0.0-20190806143415-35ef2682e516 // indirect
 )
+
+replace github.com/AllenDang/w32 => ./packages/w32
diff --git a/go.sum b/go.sum
index d443f7d0..4b9dfda5 100644
--- a/go.sum
+++ b/go.sum
@@ -1,12 +1,18 @@
 0xacab.org/leap/go-dialog v0.0.0-20181123042829-0ee8438431a0 h1:VNfk6egmYevGIKJVGVxpOyQ5rBR1DUQimrpeGxLSNsg=
 0xacab.org/leap/go-dialog v0.0.0-20181123042829-0ee8438431a0/go.mod h1:VZeIZ8qdzi4glGby9mBMNBMnvG2dV1A9nBpKy2d0JNA=
+github.com/AllenDang/w32 v0.0.0-20180428130237-ad0a36d80adc h1:w3fW4b1hPf6/cfdQQ/vu9V8eBeQmuLZIaUMj81nIzYQ=
 github.com/AllenDang/w32 v0.0.0-20180428130237-ad0a36d80adc/go.mod h1:1rHKulT5eD2DzdKxDXUZRKtBfkTzLmTL42ZmEmOfyrs=
+github.com/BurntSushi/freetype-go v0.0.0-20160129220410-b763ddbfe298/go.mod h1:D+QujdIlUNfa0igpNMk6UIvlb6C252URs4yupRUV4lQ=
+github.com/BurntSushi/graphics-go v0.0.0-20160129215708-b43f31a4a966/go.mod h1:Mid70uvE93zn9wgF92A/r5ixgnvX8Lh68fxp9KQBaI0=
+github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
+github.com/BurntSushi/xgbutil v0.0.0-20160919175755-f7c97cef3b4e/go.mod h1:uw9h2sd4WWHOPdJ13MQpwK5qYWKYDumDqxWWIknEQ+k=
 github.com/ProtonMail/go-autostart v0.0.0-20181114175602-c5272053443a h1:fXK2KsfnkBV9Nh+9SKzHchYjuE9s0vI20JG1mbtEAcc=
 github.com/ProtonMail/go-autostart v0.0.0-20181114175602-c5272053443a/go.mod h1:oTGdE7/DlWIr23G0IKW3OXK9wZ5Hw1GGiaJFccTvZi4=
+github.com/TheTitanrain/w32 v0.0.0-20180517000239-4f5cfb03fabf/go.mod h1:peYoMncQljjNS6tZwI9WVyQB3qZS6u79/N3mBOcnd3I=
 github.com/apparentlymart/go-openvpn-mgmt v0.0.0-20161009010951-9a305aecd7f2 h1:E7mgGSu7JSN+ELgOq2Pddy8fVfAbMN8u1jUvpKpHtXg=
 github.com/apparentlymart/go-openvpn-mgmt v0.0.0-20161009010951-9a305aecd7f2/go.mod h1:69IHK2p7ZvTuKqxDx3vRWZRyBhLh2rNJN3b6XnjCVhY=
-github.com/cratonica/2goarray v0.0.0-20190331194516-514510793eaa h1:Wg+722vs7a2zQH5lR9QWYsVbplKeffaQFIs5FTdfNNo=
-github.com/cratonica/2goarray v0.0.0-20190331194516-514510793eaa/go.mod h1:6Arca19mRx58CA7OWEd7Wu1NpC1rd3uDnNs6s1pj/DI=
+github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 h1:NRUJuo3v3WGC/g5YiyF790gut6oQr5f3FBI88Wv0dx4=
 github.com/getlantern/context v0.0.0-20190109183933-c447772a6520/go.mod h1:L+mq6/vvYHKjCX2oez0CgEAJmbq1fbb/oNJIWQkBybY=
 github.com/getlantern/errors v0.0.0-20180829142810-e24b7f4ff7c7 h1:pKm0g6hKvbd09FUAfFdlGBV/1L1e2KnXsapRNR6Z5/E=
@@ -23,31 +29,34 @@ github.com/getlantern/systray v0.0.0-20190626064521-f2fa635d0474 h1:ylLoQ/eTNhtZ
 github.com/getlantern/systray v0.0.0-20190626064521-f2fa635d0474/go.mod h1:7Splj4WBQSps8jODnMgrIV6goKL0N1HR+mhCAEVWlA0=
 github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
-github.com/golang/text v0.3.0 h1:uI5zIUA9cg047ctlTptnVc0Ghjfurf2eZMFrod8R7v8=
-github.com/golang/text v0.3.0/go.mod h1:GUiq9pdJKRKKAZXiVgWFEvocYuREvC14NhI4OPgEjeE=
 github.com/gotk3/gotk3 v0.0.0-20190108052711-d09d58ef3476 h1:jiDcHh/HCWp8A63RVSCB2q36Nh0WItmjgA89SzUvtoc=
 github.com/gotk3/gotk3 v0.0.0-20190108052711-d09d58ef3476/go.mod h1:Eew3QBwAOBTrfFFDmsDE5wZWbcagBL1NUslj1GhRveo=
 github.com/jmshal/go-locale v0.0.0-20161107082030-4f541412d67a h1:y9bB+vmwCNXcmu/bW89rBeVcK0PCMQJmemA+ExoP9So=
 github.com/jmshal/go-locale v0.0.0-20161107082030-4f541412d67a/go.mod h1:+Ny9b1U6p4zX0L9w+k3hSkz3puupLFP14Mion+rGNF8=
+github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 h1:iQTw/8FWTuc7uiaSepXwyf3o52HaUYcV+Tu66S3F5GA=
+github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
+github.com/mattn/go-gtk v0.0.0-20180216084204-5a311a1830ab/go.mod h1:PwzwfeB5syFHXORC3MtPylVcjIoTDT/9cvkKpEndGVI=
+github.com/mattn/go-pointer v0.0.0-20171114154726-1d30dc4b6f28/go.mod h1:2zXcozF6qYGgmsG+SeTZz3oAbFLdD3OWqnUbNvJZAlc=
 github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936 h1:kw1v0NlnN+GZcU8Ma8CLF2Zzgjfx95gs3/GN3vYAPpo=
 github.com/mitchellh/go-ps v0.0.0-20170309133038-4fdf99ab2936/go.mod h1:r1VsdOzOPt1ZSrGZWFoNhsAedKnEd6r9Np1+5blZCWk=
 github.com/oxtoacart/bpool v0.0.0-20150712133111-4e1c5567d7c2 h1:CXwSGu/LYmbjEab5aMCs5usQRVBGThelUKBNnoSOuso=
 github.com/oxtoacart/bpool v0.0.0-20150712133111-4e1c5567d7c2/go.mod h1:L3UMQOThbttwfYRNFOWLLVXMhk5Lkio4GGOtw5UrxS0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/sevlyar/go-daemon v0.1.5 h1:Zy/6jLbM8CfqJ4x4RPr7MJlSKt90f00kNM1D401C+Qk=
 github.com/sevlyar/go-daemon v0.1.5/go.mod h1:6dJpPatBT9eUwM5VCw9Bt6CdX9Tk6UWvhW3MebLDRKE=
+github.com/skelterjohn/go.wde v0.0.0-20180104102407-a0324cbf3ffe/go.mod h1:zXxNsJHeUYIqpg890APBNEn9GoCbA4Cdnvuv3mx4fBk=
 github.com/skratchdot/open-golang v0.0.0-20190104022628-a2dfa6d0dab6 h1:cGT4dcuEyBwwu/v6tosyqcDp2yoIo/LwjMGixUvg3nU=
 github.com/skratchdot/open-golang v0.0.0-20190104022628-a2dfa6d0dab6/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
+github.com/sqweek/dialog v0.0.0-20190728103509-6254ed5b0d3c h1:nQyaARR8WzWW4/AoxpyPA82gJcvuZUxLxnMqVbmW50A=
+github.com/sqweek/dialog v0.0.0-20190728103509-6254ed5b0d3c/go.mod h1:QSrNdZLZB8VoFPGlZ2vDuA2oNaVdhld3g0PZLc7soX8=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
-golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4 h1:HuIa8hRrWRSrqYzx1qI49NNxhdi2PrY7gxVSq1JjLDc=
-golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7 h1:LepdCS8Gf/MVejFIt8lsiexZATdoGVyp5bcyS+rYoUI=
-golang.org/x/sys v0.0.0-20190712062909-fae7ac547cb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa h1:KIDDMLT1O0Nr7TSxp8xM5tJcdn8tgyAONntO829og1M=
 golang.org/x/sys v0.0.0-20190804053845-51ab0e2deafa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
@@ -55,7 +64,9 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190206221403-44bcb96178d3 h1:M9mD7d4inzK0+YbTneZEs9Y+q1B1zLv8YxJDJ6hFgnY=
-golang.org/x/tools v0.0.0-20190206221403-44bcb96178d3/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190806143415-35ef2682e516 h1:r360bnWZkNIjtDFjRC/LVCPgL7sVglqb4XuifefgtB8=
 golang.org/x/tools v0.0.0-20190806143415-35ef2682e516/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
+gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/packages/w32/AUTHORS b/packages/w32/AUTHORS
new file mode 100644
index 00000000..93ec5dba
--- /dev/null
+++ b/packages/w32/AUTHORS
@@ -0,0 +1,19 @@
+# This is the official list of 'w32' authors for copyright purposes.
+
+# Names should be added to this file as
+#   Name or Organization <email address>
+# The email address is not required for organizations.
+
+# Please keep the list sorted.
+
+# Contributors
+# ============
+
+Allen Dang <allengnr@gmail.com>
+Benny Siegert <bsiegert@gmail.com>
+Bruno Bigras <bigras.bruno@gmail.com>
+Daniel Joos
+Gerald Rosenberg <gerald.rosenberg@gmail.com>
+Liam Bowen <liambowen@gmail.com>
+Michael Henke
+Paul Maddox <paul.maddox@gmail.com>
\ No newline at end of file
diff --git a/packages/w32/LICENSE b/packages/w32/LICENSE
new file mode 100644
index 00000000..9f36608c
--- /dev/null
+++ b/packages/w32/LICENSE
@@ -0,0 +1,23 @@
+Copyright (c) 2010-2012 The w32 Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+3. The names of the authors may not be used to endorse or promote products
+   derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/packages/w32/README.md b/packages/w32/README.md
new file mode 100644
index 00000000..ed196e76
--- /dev/null
+++ b/packages/w32/README.md
@@ -0,0 +1,33 @@
+About w32
+==========
+
+w32 is a wrapper of windows apis for the Go Programming Language.
+
+It wraps win32 apis to "Go style" to make them easier to use.
+
+Setup
+=====
+
+1. Make sure you have a working Go installation and build environment, 
+   see this go-nuts post for details:
+   http://groups.google.com/group/golang-nuts/msg/5c87630a84f4fd0c
+   
+   Updated versions of the Windows Go build are available here:
+   http://code.google.com/p/gomingw/downloads/list
+   
+2. Create a "gopath" directory if you do not have one yet and set the
+   GOPATH variable accordingly. For example:
+   mkdir -p go-externals/src
+   export GOPATH=${PWD}/go-externals
+
+3. go get github.com/AllenDang/w32
+
+4. go install github.com/AllenDang/w32...
+
+Contribute
+==========
+
+Contributions in form of design, code, documentation, bug reporting or other
+ways you see fit are very welcome.
+
+Thank You!
diff --git a/packages/w32/advapi32.go b/packages/w32/advapi32.go
new file mode 100644
index 00000000..10e1416c
--- /dev/null
+++ b/packages/w32/advapi32.go
@@ -0,0 +1,389 @@
+// Copyright 2010-2012 The W32 Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package w32
+
+import (
+	"errors"
+	"fmt"
+	"syscall"
+	"unsafe"
+)
+
+var (
+	modadvapi32 = syscall.NewLazyDLL("advapi32.dll")
+
+	//	procRegSetKeyValue     = modadvapi32.NewProc("RegSetKeyValueW")
+	procCloseEventLog                = modadvapi32.NewProc("CloseEventLog")
+	procCloseServiceHandle           = modadvapi32.NewProc("CloseServiceHandle")
+	procControlService               = modadvapi32.NewProc("ControlService")
+	procControlTrace                 = modadvapi32.NewProc("ControlTraceW")
+	procInitializeSecurityDescriptor = modadvapi32.NewProc("InitializeSecurityDescriptor")
+	procOpenEventLog                 = modadvapi32.NewProc("OpenEventLogW")
+	procOpenSCManager                = modadvapi32.NewProc("OpenSCManagerW")
+	procOpenService                  = modadvapi32.NewProc("OpenServiceW")
+	procReadEventLog                 = modadvapi32.NewProc("ReadEventLogW")
+	procRegCloseKey                  = modadvapi32.NewProc("RegCloseKey")
+	procRegCreateKeyEx               = modadvapi32.NewProc("RegCreateKeyExW")
+	procRegEnumKeyEx                 = modadvapi32.NewProc("RegEnumKeyExW")
+	procRegGetValue                  = modadvapi32.NewProc("RegGetValueW")
+	procRegOpenKeyEx                 = modadvapi32.NewProc("RegOpenKeyExW")
+	procRegSetValueEx                = modadvapi32.NewProc("RegSetValueExW")
+	procSetSecurityDescriptorDacl    = modadvapi32.NewProc("SetSecurityDescriptorDacl")
+	procStartService                 = modadvapi32.NewProc("StartServiceW")
+	procStartTrace                   = modadvapi32.NewProc("StartTraceW")
+)
+
+var (
+	SystemTraceControlGuid = GUID{
+		0x9e814aad,
+		0x3204,
+		0x11d2,
+		[8]byte{0x9a, 0x82, 0x00, 0x60, 0x08, 0xa8, 0x69, 0x39},
+	}
+)
+
+func RegCreateKey(hKey HKEY, subKey string) HKEY {
+	var result HKEY
+	ret, _, _ := procRegCreateKeyEx.Call(
+		uintptr(hKey),
+		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
+		uintptr(0),
+		uintptr(0),
+		uintptr(0),
+		uintptr(KEY_ALL_ACCESS),
+		uintptr(0),
+		uintptr(unsafe.Pointer(&result)),
+		uintptr(0))
+	_ = ret
+	return result
+}
+
+func RegOpenKeyEx(hKey HKEY, subKey string, samDesired uint32) HKEY {
+	var result HKEY
+	ret, _, _ := procRegOpenKeyEx.Call(
+		uintptr(hKey),
+		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
+		uintptr(0),
+		uintptr(samDesired),
+		uintptr(unsafe.Pointer(&result)))
+
+	if ret != ERROR_SUCCESS {
+		panic(fmt.Sprintf("RegOpenKeyEx(%d, %s, %d) failed", hKey, subKey, samDesired))
+	}
+	return result
+}
+
+func RegCloseKey(hKey HKEY) error {
+	var err error
+	ret, _, _ := procRegCloseKey.Call(
+		uintptr(hKey))
+
+	if ret != ERROR_SUCCESS {
+		err = errors.New("RegCloseKey failed")
+	}
+	return err
+}
+
+func RegGetRaw(hKey HKEY, subKey string, value string) []byte {
+	var bufLen uint32
+	var valptr unsafe.Pointer
+	if len(value) > 0 {
+		valptr = unsafe.Pointer(syscall.StringToUTF16Ptr(value))
+	}
+	procRegGetValue.Call(
+		uintptr(hKey),
+		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
+		uintptr(valptr),
+		uintptr(RRF_RT_ANY),
+		0,
+		0,
+		uintptr(unsafe.Pointer(&bufLen)))
+
+	if bufLen == 0 {
+		return nil
+	}
+
+	buf := make([]byte, bufLen)
+	ret, _, _ := procRegGetValue.Call(
+		uintptr(hKey),
+		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
+		uintptr(valptr),
+		uintptr(RRF_RT_ANY),
+		0,
+		uintptr(unsafe.Pointer(&buf[0])),
+		uintptr(unsafe.Pointer(&bufLen)))
+
+	if ret != ERROR_SUCCESS {
+		return nil
+	}
+
+	return buf
+}
+
+func RegSetBinary(hKey HKEY, subKey string, value []byte) (errno int) {
+	var lptr, vptr unsafe.Pointer
+	if len(subKey) > 0 {
+		lptr = unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))
+	}
+	if len(value) > 0 {
+		vptr = unsafe.Pointer(&value[0])
+	}
+	ret, _, _ := procRegSetValueEx.Call(
+		uintptr(hKey),
+		uintptr(lptr),
+		uintptr(0),
+		uintptr(REG_BINARY),
+		uintptr(vptr),
+		uintptr(len(value)))
+
+	return int(ret)
+}
+
+func RegGetString(hKey HKEY, subKey string, value string) string {
+	var bufLen uint32
+	procRegGetValue.Call(
+		uintptr(hKey),
+		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
+		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(value))),
+		uintptr(RRF_RT_REG_SZ),
+		0,
+		0,
+		uintptr(unsafe.Pointer(&bufLen)))
+
+	if bufLen == 0 {
+		return ""
+	}
+
+	buf := make([]uint16, bufLen)
+	ret, _, _ := procRegGetValue.Call(
+		uintptr(hKey),
+		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
+		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(value))),
+		uintptr(RRF_RT_REG_SZ),
+		0,
+		uintptr(unsafe.Pointer(&buf[0])),
+		uintptr(unsafe.Pointer(&bufLen)))
+
+	if ret != ERROR_SUCCESS {
+		return ""
+	}
+
+	return syscall.UTF16ToString(buf)
+}
+
+/*
+func RegSetKeyValue(hKey HKEY, subKey string, valueName string, dwType uint32, data uintptr, cbData uint16) (errno int) {
+	ret, _, _ := procRegSetKeyValue.Call(
+		uintptr(hKey),
+		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
+		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(valueName))),
+		uintptr(dwType),
+		data,
+		uintptr(cbData))
+
+	return int(ret)
+}
+*/
+
+func RegEnumKeyEx(hKey HKEY, index uint32) string {
+	var bufLen uint32 = 255
+	buf := make([]uint16, bufLen)
+	procRegEnumKeyEx.Call(
+		uintptr(hKey),
+		uintptr(index),
+		uintptr(unsafe.Pointer(&buf[0])),
+		uintptr(unsafe.Pointer(&bufLen)),
+		0,
+		0,
+		0,
+		0)
+	return syscall.UTF16ToString(buf)
+}
+
+func OpenEventLog(servername string, sourcename string) HANDLE {
+	ret, _, _ := procOpenEventLog.Call(
+		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(servername))),
+		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(sourcename))))
+
+	return HANDLE(ret)
+}
+
+func ReadEventLog(eventlog HANDLE, readflags, recordoffset uint32, buffer []byte, numberofbytestoread uint32, bytesread, minnumberofbytesneeded *uint32) bool {
+	ret, _, _ := procReadEventLog.Call(
+		uintptr(eventlog),
+		uintptr(readflags),
+		uintptr(recordoffset),
+		uintptr(unsafe.Pointer(&buffer[0])),
+		uintptr(numberofbytestoread),
+		uintptr(unsafe.Pointer(bytesread)),
+		uintptr(unsafe.Pointer(minnumberofbytesneeded)))
+
+	return ret != 0
+}
+
+func CloseEventLog(eventlog HANDLE) bool {
+	ret, _, _ := procCloseEventLog.Call(
+		uintptr(eventlog))
+
+	return ret != 0
+}
+
+func OpenSCManager(lpMachineName, lpDatabaseName string, dwDesiredAccess uint32) (HANDLE, error) {
+	var p1, p2 uintptr
+	if len(lpMachineName) > 0 {
+		p1 = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpMachineName)))
+	}
+	if len(lpDatabaseName) > 0 {
+		p2 = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpDatabaseName)))
+	}
+	ret, _, _ := procOpenSCManager.Call(
+		p1,
+		p2,
+		uintptr(dwDesiredAccess))
+
+	if ret == 0 {
+		return 0, syscall.GetLastError()
+	}
+
+	return HANDLE(ret), nil
+}
+
+func CloseServiceHandle(hSCObject HANDLE) error {
+	ret, _, _ := procCloseServiceHandle.Call(uintptr(hSCObject))
+	if ret == 0 {
+		return syscall.GetLastError()
+	}
+	return nil
+}
+
+func OpenService(hSCManager HANDLE, lpServiceName string, dwDesiredAccess uint32) (HANDLE, error) {
+	ret, _, _ := procOpenService.Call(
+		uintptr(hSCManager),
+		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpServiceName))),
+		uintptr(dwDesiredAccess))
+
+	if ret == 0 {
+		return 0, syscall.GetLastError()
+	}
+
+	return HANDLE(ret), nil
+}
+
+func StartService(hService HANDLE, lpServiceArgVectors []string) error {
+	l := len(lpServiceArgVectors)
+	var ret uintptr
+	if l == 0 {
+		ret, _, _ = procStartService.Call(
+			uintptr(hService),
+			0,
+			0)
+	} else {
+		lpArgs := make([]uintptr, l)
+		for i := 0; i < l; i++ {
+			lpArgs[i] = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpServiceArgVectors[i])))
+		}
+
+		ret, _, _ = procStartService.Call(
+			uintptr(hService),
+			uintptr(l),
+			uintptr(unsafe.Pointer(&lpArgs[0])))
+	}
+
+	if ret == 0 {
+		return syscall.GetLastError()
+	}
+
+	return nil
+}
+
+func ControlService(hService HANDLE, dwControl uint32, lpServiceStatus *SERVICE_STATUS) bool {
+	if lpServiceStatus == nil {
+		panic("ControlService:lpServiceStatus cannot be nil")
+	}
+
+	ret, _, _ := procControlService.Call(
+		uintptr(hService),
+		uintptr(dwControl),
+		uintptr(unsafe.Pointer(lpServiceStatus)))
+
+	return ret != 0
+}
+
+func ControlTrace(hTrace TRACEHANDLE, lpSessionName string, props *EVENT_TRACE_PROPERTIES, dwControl uint32) (success bool, e error) {
+
+	ret, _, _ := procControlTrace.Call(
+		uintptr(unsafe.Pointer(hTrace)),
+		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpSessionName))),
+		uintptr(unsafe.Pointer(props)),
+		uintptr(dwControl))
+
+	if ret == ERROR_SUCCESS {
+		return true, nil
+	}
+	e = errors.New(fmt.Sprintf("error: 0x%x", ret))
+	return
+}
+
+func StartTrace(lpSessionName string, props *EVENT_TRACE_PROPERTIES) (hTrace TRACEHANDLE, e error) {
+
+	ret, _, _ := procStartTrace.Call(
+		uintptr(unsafe.Pointer(&hTrace)),
+		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpSessionName))),
+		uintptr(unsafe.Pointer(props)))
+
+	if ret == ERROR_SUCCESS {
+		return
+	}
+	e = errors.New(fmt.Sprintf("error: 0x%x", ret))
+	return
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/aa378863(v=vs.85).aspx
+func InitializeSecurityDescriptor(rev uint16) (pSecurityDescriptor *SECURITY_DESCRIPTOR, e error) {
+
+	pSecurityDescriptor = &SECURITY_DESCRIPTOR{}
+
+	ret, _, _ := procInitializeSecurityDescriptor.Call(
+		uintptr(unsafe.Pointer(pSecurityDescriptor)),
+		uintptr(rev),
+	)
+
+	if ret != 0 {
+		return
+	}
+	e = syscall.GetLastError()
+	return
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/aa379583(v=vs.85).aspx
+func SetSecurityDescriptorDacl(pSecurityDescriptor *SECURITY_DESCRIPTOR, pDacl *ACL) (e error) {
+
+	if pSecurityDescriptor == nil {
+		return errors.New("null descriptor")
+	}
+
+	var ret uintptr
+	if pDacl == nil {
+		ret, _, _ = procSetSecurityDescriptorDacl.Call(
+			uintptr(unsafe.Pointer(pSecurityDescriptor)),
+			uintptr(1), // DaclPresent
+			uintptr(0), // pDacl
+			uintptr(0), // DaclDefaulted
+		)
+	} else {
+		ret, _, _ = procSetSecurityDescriptorDacl.Call(
+			uintptr(unsafe.Pointer(pSecurityDescriptor)),
+			uintptr(1), // DaclPresent
+			uintptr(unsafe.Pointer(pDacl)),
+			uintptr(0), //DaclDefaulted
+		)
+	}
+
+	if ret != 0 {
+		return
+	}
+	e = syscall.GetLastError()
+	return
+}
diff --git a/packages/w32/advapi32_constants.go b/packages/w32/advapi32_constants.go
new file mode 100644
index 00000000..fa3c7674
--- /dev/null
+++ b/packages/w32/advapi32_constants.go
@@ -0,0 +1,300 @@
+package w32
+
+// Registry predefined keys
+const (
+	HKEY_CLASSES_ROOT     HKEY = 0x80000000
+	HKEY_CURRENT_USER     HKEY = 0x80000001
+	HKEY_LOCAL_MACHINE    HKEY = 0x80000002
+	HKEY_USERS            HKEY = 0x80000003
+	HKEY_PERFORMANCE_DATA HKEY = 0x80000004
+	HKEY_CURRENT_CONFIG   HKEY = 0x80000005
+	HKEY_DYN_DATA         HKEY = 0x80000006
+)
+
+// Registry Key Security and Access Rights
+const (
+	KEY_ALL_ACCESS         = 0xF003F
+	KEY_CREATE_SUB_KEY     = 0x0004
+	KEY_ENUMERATE_SUB_KEYS = 0x0008
+	KEY_NOTIFY             = 0x0010
+	KEY_QUERY_VALUE        = 0x0001
+	KEY_SET_VALUE          = 0x0002
+	KEY_READ               = 0x20019
+	KEY_WRITE              = 0x20006
+)
+
+const (
+	NFR_ANSI    = 1
+	NFR_UNICODE = 2
+	NF_QUERY    = 3
+	NF_REQUERY  = 4
+)
+
+// Registry value types
+const (
+	RRF_RT_REG_NONE         = 0x00000001
+	RRF_RT_REG_SZ           = 0x00000002
+	RRF_RT_REG_EXPAND_SZ    = 0x00000004
+	RRF_RT_REG_BINARY       = 0x00000008
+	RRF_RT_REG_DWORD        = 0x00000010
+	RRF_RT_REG_MULTI_SZ     = 0x00000020
+	RRF_RT_REG_QWORD        = 0x00000040
+	RRF_RT_DWORD            = (RRF_RT_REG_BINARY | RRF_RT_REG_DWORD)
+	RRF_RT_QWORD            = (RRF_RT_REG_BINARY | RRF_RT_REG_QWORD)
+	RRF_RT_ANY              = 0x0000ffff
+	RRF_NOEXPAND            = 0x10000000
+	RRF_ZEROONFAILURE       = 0x20000000
+	REG_PROCESS_APPKEY      = 0x00000001
+	REG_MUI_STRING_TRUNCATE = 0x00000001
+)
+
+// Service Control Manager object specific access types
+const (
+	SC_MANAGER_CONNECT            = 0x0001
+	SC_MANAGER_CREATE_SERVICE     = 0x0002
+	SC_MANAGER_ENUMERATE_SERVICE  = 0x0004
+	SC_MANAGER_LOCK               = 0x0008
+	SC_MANAGER_QUERY_LOCK_STATUS  = 0x0010
+	SC_MANAGER_MODIFY_BOOT_CONFIG = 0x0020
+	SC_MANAGER_ALL_ACCESS         = STANDARD_RIGHTS_REQUIRED | SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE | SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_LOCK | SC_MANAGER_QUERY_LOCK_STATUS | SC_MANAGER_MODIFY_BOOT_CONFIG
+)
+
+// Service Types (Bit Mask)
+const (
+	SERVICE_KERNEL_DRIVER       = 0x00000001
+	SERVICE_FILE_SYSTEM_DRIVER  = 0x00000002
+	SERVICE_ADAPTER             = 0x00000004
+	SERVICE_RECOGNIZER_DRIVER   = 0x00000008
+	SERVICE_DRIVER              = SERVICE_KERNEL_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_RECOGNIZER_DRIVER
+	SERVICE_WIN32_OWN_PROCESS   = 0x00000010
+	SERVICE_WIN32_SHARE_PROCESS = 0x00000020
+	SERVICE_WIN32               = SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS
+	SERVICE_INTERACTIVE_PROCESS = 0x00000100
+	SERVICE_TYPE_ALL            = SERVICE_WIN32 | SERVICE_ADAPTER | SERVICE_DRIVER | SERVICE_INTERACTIVE_PROCESS
+)
+
+// Service State -- for CurrentState
+const (
+	SERVICE_STOPPED          = 0x00000001
+	SERVICE_START_PENDING    = 0x00000002
+	SERVICE_STOP_PENDING     = 0x00000003
+	SERVICE_RUNNING          = 0x00000004
+	SERVICE_CONTINUE_PENDING = 0x00000005
+	SERVICE_PAUSE_PENDING    = 0x00000006
+	SERVICE_PAUSED           = 0x00000007
+)
+
+// Controls Accepted  (Bit Mask)
+const (
+	SERVICE_ACCEPT_STOP                  = 0x00000001
+	SERVICE_ACCEPT_PAUSE_CONTINUE        = 0x00000002
+	SERVICE_ACCEPT_SHUTDOWN              = 0x00000004
+	SERVICE_ACCEPT_PARAMCHANGE           = 0x00000008
+	SERVICE_ACCEPT_NETBINDCHANGE         = 0x00000010
+	SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 0x00000020
+	SERVICE_ACCEPT_POWEREVENT            = 0x00000040
+	SERVICE_ACCEPT_SESSIONCHANGE         = 0x00000080
+	SERVICE_ACCEPT_PRESHUTDOWN           = 0x00000100
+	SERVICE_ACCEPT_TIMECHANGE            = 0x00000200
+	SERVICE_ACCEPT_TRIGGEREVENT          = 0x00000400
+)
+
+// Service object specific access type
+const (
+	SERVICE_QUERY_CONFIG         = 0x0001
+	SERVICE_CHANGE_CONFIG        = 0x0002
+	SERVICE_QUERY_STATUS         = 0x0004
+	SERVICE_ENUMERATE_DEPENDENTS = 0x0008
+	SERVICE_START                = 0x0010
+	SERVICE_STOP                 = 0x0020
+	SERVICE_PAUSE_CONTINUE       = 0x0040
+	SERVICE_INTERROGATE          = 0x0080
+	SERVICE_USER_DEFINED_CONTROL = 0x0100
+
+	SERVICE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED |
+		SERVICE_QUERY_CONFIG |
+		SERVICE_CHANGE_CONFIG |
+		SERVICE_QUERY_STATUS |
+		SERVICE_ENUMERATE_DEPENDENTS |
+		SERVICE_START |
+		SERVICE_STOP |
+		SERVICE_PAUSE_CONTINUE |
+		SERVICE_INTERROGATE |
+		SERVICE_USER_DEFINED_CONTROL
+)
+
+const (
+	KERNEL_LOGGER_NAME = "NT Kernel Logger"
+)
+
+// WNODE flags, for ETW (Event Tracing for Windows) / WMI
+const (
+	WNODE_FLAG_ALL_DATA              = 0x00000001
+	WNODE_FLAG_SINGLE_INSTANCE       = 0x00000002
+	WNODE_FLAG_SINGLE_ITEM           = 0x00000004
+	WNODE_FLAG_EVENT_ITEM            = 0x00000008
+	WNODE_FLAG_FIXED_INSTANCE_SIZE   = 0x00000010
+	WNODE_FLAG_TOO_SMALL             = 0x00000020
+	WNODE_FLAG_INSTANCES_SAME        = 0x00000040
+	WNODE_FLAG_STATIC_INSTANCE_NAMES = 0x00000080
+	WNODE_FLAG_INTERNAL              = 0x00000100
+	WNODE_FLAG_USE_TIMESTAMP         = 0x00000200
+	WNODE_FLAG_PERSIST_EVENT         = 0x00000400
+	WNODE_FLAG_EVENT_REFERENCE       = 0x00002000
+	WNODE_FLAG_ANSI_INSTANCENAMES    = 0x00004000
+	WNODE_FLAG_METHOD_ITEM           = 0x00008000
+	WNODE_FLAG_PDO_INSTANCE_NAMES    = 0x00010000
+	WNODE_FLAG_TRACED_GUID           = 0x00020000
+	WNODE_FLAG_LOG_WNODE             = 0x00040000
+	WNODE_FLAG_USE_GUID_PTR          = 0x00080000
+	WNODE_FLAG_USE_MOF_PTR           = 0x00100000
+	WNODE_FLAG_NO_HEADER             = 0x00200000
+	WNODE_FLAG_SEVERITY_MASK         = 0xff000000
+)
+
+// ETW flags and types etc
+const (
+	EVENT_TRACE_TYPE_INFO                  = 0x00
+	EVENT_TRACE_TYPE_START                 = 0x01
+	EVENT_TRACE_TYPE_END                   = 0x02
+	EVENT_TRACE_TYPE_STOP                  = 0x02
+	EVENT_TRACE_TYPE_DC_START              = 0x03
+	EVENT_TRACE_TYPE_DC_END                = 0x04
+	EVENT_TRACE_TYPE_EXTENSION             = 0x05
+	EVENT_TRACE_TYPE_REPLY                 = 0x06
+	EVENT_TRACE_TYPE_DEQUEUE               = 0x07
+	EVENT_TRACE_TYPE_RESUME                = 0x07
+	EVENT_TRACE_TYPE_CHECKPOINT            = 0x08
+	EVENT_TRACE_TYPE_SUSPEND               = 0x08
+	EVENT_TRACE_TYPE_WINEVT_SEND           = 0x09
+	EVENT_TRACE_TYPE_WINEVT_RECEIVE        = 0XF0
+	TRACE_LEVEL_NONE                       = 0
+	TRACE_LEVEL_CRITICAL                   = 1
+	TRACE_LEVEL_FATAL                      = 1
+	TRACE_LEVEL_ERROR                      = 2
+	TRACE_LEVEL_WARNING                    = 3
+	TRACE_LEVEL_INFORMATION                = 4
+	TRACE_LEVEL_VERBOSE                    = 5
+	TRACE_LEVEL_RESERVED6                  = 6
+	TRACE_LEVEL_RESERVED7                  = 7
+	TRACE_LEVEL_RESERVED8                  = 8
+	TRACE_LEVEL_RESERVED9                  = 9
+	EVENT_TRACE_TYPE_LOAD                  = 0x0A
+	EVENT_TRACE_TYPE_IO_READ               = 0x0A
+	EVENT_TRACE_TYPE_IO_WRITE              = 0x0B
+	EVENT_TRACE_TYPE_IO_READ_INIT          = 0x0C
+	EVENT_TRACE_TYPE_IO_WRITE_INIT         = 0x0D
+	EVENT_TRACE_TYPE_IO_FLUSH              = 0x0E
+	EVENT_TRACE_TYPE_IO_FLUSH_INIT         = 0x0F
+	EVENT_TRACE_TYPE_MM_TF                 = 0x0A
+	EVENT_TRACE_TYPE_MM_DZF                = 0x0B
+	EVENT_TRACE_TYPE_MM_COW                = 0x0C
+	EVENT_TRACE_TYPE_MM_GPF                = 0x0D
+	EVENT_TRACE_TYPE_MM_HPF                = 0x0E
+	EVENT_TRACE_TYPE_MM_AV                 = 0x0F
+	EVENT_TRACE_TYPE_SEND                  = 0x0A
+	EVENT_TRACE_TYPE_RECEIVE               = 0x0B
+	EVENT_TRACE_TYPE_CONNECT               = 0x0C
+	EVENT_TRACE_TYPE_DISCONNECT            = 0x0D
+	EVENT_TRACE_TYPE_RETRANSMIT            = 0x0E
+	EVENT_TRACE_TYPE_ACCEPT                = 0x0F
+	EVENT_TRACE_TYPE_RECONNECT             = 0x10
+	EVENT_TRACE_TYPE_CONNFAIL              = 0x11
+	EVENT_TRACE_TYPE_COPY_TCP              = 0x12
+	EVENT_TRACE_TYPE_COPY_ARP              = 0x13
+	EVENT_TRACE_TYPE_ACKFULL               = 0x14
+	EVENT_TRACE_TYPE_ACKPART               = 0x15
+	EVENT_TRACE_TYPE_ACKDUP                = 0x16
+	EVENT_TRACE_TYPE_GUIDMAP               = 0x0A
+	EVENT_TRACE_TYPE_CONFIG                = 0x0B
+	EVENT_TRACE_TYPE_SIDINFO               = 0x0C
+	EVENT_TRACE_TYPE_SECURITY              = 0x0D
+	EVENT_TRACE_TYPE_REGCREATE             = 0x0A
+	EVENT_TRACE_TYPE_REGOPEN               = 0x0B
+	EVENT_TRACE_TYPE_REGDELETE             = 0x0C
+	EVENT_TRACE_TYPE_REGQUERY              = 0x0D
+	EVENT_TRACE_TYPE_REGSETVALUE           = 0x0E
+	EVENT_TRACE_TYPE_REGDELETEVALUE        = 0x0F
+	EVENT_TRACE_TYPE_REGQUERYVALUE         = 0x10
+	EVENT_TRACE_TYPE_REGENUMERATEKEY       = 0x11
+	EVENT_TRACE_TYPE_REGENUMERATEVALUEKEY  = 0x12
+	EVENT_TRACE_TYPE_REGQUERYMULTIPLEVALUE = 0x13
+	EVENT_TRACE_TYPE_REGSETINFORMATION     = 0x14
+	EVENT_TRACE_TYPE_REGFLUSH              = 0x15
+	EVENT_TRACE_TYPE_REGKCBCREATE          = 0x16
+	EVENT_TRACE_TYPE_REGKCBDELETE          = 0x17
+	EVENT_TRACE_TYPE_REGKCBRUNDOWNBEGIN    = 0x18
+	EVENT_TRACE_TYPE_REGKCBRUNDOWNEND      = 0x19
+	EVENT_TRACE_TYPE_REGVIRTUALIZE         = 0x1A
+	EVENT_TRACE_TYPE_REGCLOSE              = 0x1B
+	EVENT_TRACE_TYPE_REGSETSECURITY        = 0x1C
+	EVENT_TRACE_TYPE_REGQUERYSECURITY      = 0x1D
+	EVENT_TRACE_TYPE_REGCOMMIT             = 0x1E
+	EVENT_TRACE_TYPE_REGPREPARE            = 0x1F
+	EVENT_TRACE_TYPE_REGROLLBACK           = 0x20
+	EVENT_TRACE_TYPE_REGMOUNTHIVE          = 0x21
+	EVENT_TRACE_TYPE_CONFIG_CPU            = 0x0A
+	EVENT_TRACE_TYPE_CONFIG_PHYSICALDISK   = 0x0B
+	EVENT_TRACE_TYPE_CONFIG_LOGICALDISK    = 0x0C
+	EVENT_TRACE_TYPE_CONFIG_NIC            = 0x0D
+	EVENT_TRACE_TYPE_CONFIG_VIDEO          = 0x0E
+	EVENT_TRACE_TYPE_CONFIG_SERVICES       = 0x0F
+	EVENT_TRACE_TYPE_CONFIG_POWER          = 0x10
+	EVENT_TRACE_TYPE_CONFIG_NETINFO        = 0x11
+	EVENT_TRACE_TYPE_CONFIG_IRQ            = 0x15
+	EVENT_TRACE_TYPE_CONFIG_PNP            = 0x16
+	EVENT_TRACE_TYPE_CONFIG_IDECHANNEL     = 0x17
+	EVENT_TRACE_TYPE_CONFIG_PLATFORM       = 0x19
+	EVENT_TRACE_FLAG_PROCESS               = 0x00000001
+	EVENT_TRACE_FLAG_THREAD                = 0x00000002
+	EVENT_TRACE_FLAG_IMAGE_LOAD            = 0x00000004
+	EVENT_TRACE_FLAG_DISK_IO               = 0x00000100
+	EVENT_TRACE_FLAG_DISK_FILE_IO          = 0x00000200
+	EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS    = 0x00001000
+	EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS    = 0x00002000
+	EVENT_TRACE_FLAG_NETWORK_TCPIP         = 0x00010000
+	EVENT_TRACE_FLAG_REGISTRY              = 0x00020000
+	EVENT_TRACE_FLAG_DBGPRINT              = 0x00040000
+	EVENT_TRACE_FLAG_PROCESS_COUNTERS      = 0x00000008
+	EVENT_TRACE_FLAG_CSWITCH               = 0x00000010
+	EVENT_TRACE_FLAG_DPC                   = 0x00000020
+	EVENT_TRACE_FLAG_INTERRUPT             = 0x00000040
+	EVENT_TRACE_FLAG_SYSTEMCALL            = 0x00000080
+	EVENT_TRACE_FLAG_DISK_IO_INIT          = 0x00000400
+	EVENT_TRACE_FLAG_ALPC                  = 0x00100000
+	EVENT_TRACE_FLAG_SPLIT_IO              = 0x00200000
+	EVENT_TRACE_FLAG_DRIVER                = 0x00800000
+	EVENT_TRACE_FLAG_PROFILE               = 0x01000000
+	EVENT_TRACE_FLAG_FILE_IO               = 0x02000000
+	EVENT_TRACE_FLAG_FILE_IO_INIT          = 0x04000000
+	EVENT_TRACE_FLAG_DISPATCHER            = 0x00000800
+	EVENT_TRACE_FLAG_VIRTUAL_ALLOC         = 0x00004000
+	EVENT_TRACE_FLAG_EXTENSION             = 0x80000000
+	EVENT_TRACE_FLAG_FORWARD_WMI           = 0x40000000
+	EVENT_TRACE_FLAG_ENABLE_RESERVE        = 0x20000000
+	EVENT_TRACE_FILE_MODE_NONE             = 0x00000000
+	EVENT_TRACE_FILE_MODE_SEQUENTIAL       = 0x00000001
+	EVENT_TRACE_FILE_MODE_CIRCULAR         = 0x00000002
+	EVENT_TRACE_FILE_MODE_APPEND           = 0x00000004
+	EVENT_TRACE_REAL_TIME_MODE             = 0x00000100
+	EVENT_TRACE_DELAY_OPEN_FILE_MODE       = 0x00000200
+	EVENT_TRACE_BUFFERING_MODE             = 0x00000400
+	EVENT_TRACE_PRIVATE_LOGGER_MODE        = 0x00000800
+	EVENT_TRACE_ADD_HEADER_MODE            = 0x00001000
+	EVENT_TRACE_USE_GLOBAL_SEQUENCE        = 0x00004000
+	EVENT_TRACE_USE_LOCAL_SEQUENCE         = 0x00008000
+	EVENT_TRACE_RELOG_MODE                 = 0x00010000
+	EVENT_TRACE_USE_PAGED_MEMORY           = 0x01000000
+	EVENT_TRACE_FILE_MODE_NEWFILE          = 0x00000008
+	EVENT_TRACE_FILE_MODE_PREALLOCATE      = 0x00000020
+	EVENT_TRACE_NONSTOPPABLE_MODE          = 0x00000040
+	EVENT_TRACE_SECURE_MODE                = 0x00000080
+	EVENT_TRACE_USE_KBYTES_FOR_SIZE        = 0x00002000
+	EVENT_TRACE_PRIVATE_IN_PROC            = 0x00020000
+	EVENT_TRACE_MODE_RESERVED              = 0x00100000
+	EVENT_TRACE_NO_PER_PROCESSOR_BUFFERING = 0x10000000
+	EVENT_TRACE_CONTROL_QUERY              = 0
+	EVENT_TRACE_CONTROL_STOP               = 1
+	EVENT_TRACE_CONTROL_UPDATE             = 2
+	EVENT_TRACE_CONTROL_FLUSH              = 3
+)
diff --git a/packages/w32/advapi32_typedef.go b/packages/w32/advapi32_typedef.go
new file mode 100644
index 00000000..3a4308c4
--- /dev/null
+++ b/packages/w32/advapi32_typedef.go
@@ -0,0 +1,122 @@
+package w32
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/aa374931(v=vs.85).aspx
+type ACL struct {
+	AclRevision byte
+	Sbz1        byte
+	AclSize     uint16
+	AceCount    uint16
+	Sbz2        uint16
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/aa379561(v=vs.85).aspx
+
+type SECURITY_DESCRIPTOR_CONTROL uint16
+
+type SECURITY_DESCRIPTOR struct {
+	Revision byte
+	Sbz1     byte
+	Control  SECURITY_DESCRIPTOR_CONTROL
+	Owner    uintptr
+	Group    uintptr
+	Sacl     *ACL
+	Dacl     *ACL
+}
+
+type SID_IDENTIFIER_AUTHORITY struct {
+	Value [6]byte
+}
+
+// typedef struct _SID // 4 elements, 0xC bytes (sizeof)
+// {
+// /*0x000*/     UINT8        Revision;
+// /*0x001*/     UINT8        SubAuthorityCount;
+// /*0x002*/     struct _SID_IDENTIFIER_AUTHORITY IdentifierAuthority; // 1 elements, 0x6 bytes (sizeof)
+// /*0x008*/     ULONG32      SubAuthority[1];
+// }SID, *PSID;
+type SID struct {
+	Revision            byte
+	SubAuthorityCount   byte
+	IdentifierAuthority SID_IDENTIFIER_AUTHORITY
+	SubAuthority        uint32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/aa363646.aspx
+type EVENTLOGRECORD struct {
+	Length              uint32
+	Reserved            uint32
+	RecordNumber        uint32
+	TimeGenerated       uint32
+	TimeWritten         uint32
+	EventID             uint32
+	EventType           uint16
+	NumStrings          uint16
+	EventCategory       uint16
+	ReservedFlags       uint16
+	ClosingRecordNumber uint32
+	StringOffset        uint32
+	UserSidLength       uint32
+	UserSidOffset       uint32
+	DataLength          uint32
+	DataOffset          uint32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/ms685996.aspx
+type SERVICE_STATUS struct {
+	DwServiceType             uint32
+	DwCurrentState            uint32
+	DwControlsAccepted        uint32
+	DwWin32ExitCode           uint32
+	DwServiceSpecificExitCode uint32
+	DwCheckPoint              uint32
+	DwWaitHint                uint32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/aa364160(v=vs.85).aspx
+type WNODE_HEADER struct {
+	BufferSize        uint32
+	ProviderId        uint32
+	HistoricalContext uint64
+	KernelHandle      HANDLE
+	Guid              GUID
+	ClientContext     uint32
+	Flags             uint32
+}
+
+// These partially compensate for the anonymous unions we removed, but there
+// are no setters.
+func (w WNODE_HEADER) TimeStamp() uint64 {
+	// TODO: Cast to the stupid LARGE_INTEGER struct which is, itself, nasty
+	// and union-y
+	return uint64(w.KernelHandle)
+}
+
+func (w WNODE_HEADER) Version() uint32 {
+	return uint32(w.HistoricalContext >> 32)
+}
+
+func (w WNODE_HEADER) Linkage() uint32 {
+	return uint32(w.HistoricalContext)
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/aa363784(v=vs.85).aspx
+type EVENT_TRACE_PROPERTIES struct {
+	Wnode               WNODE_HEADER
+	BufferSize          uint32
+	MinimumBuffers      uint32
+	MaximumBuffers      uint32
+	MaximumFileSize     uint32
+	LogFileMode         uint32
+	FlushTimer          uint32
+	EnableFlags         uint32
+	AgeLimit            int32
+	NumberOfBuffers     uint32
+	FreeBuffers         uint32
+	EventsLost          uint32
+	BuffersWritten      uint32
+	LogBuffersLost      uint32
+	RealTimeBuffersLost uint32
+	LoggerThreadId      HANDLE
+	LogFileNameOffset   uint32
+	LoggerNameOffset    uint32
+}
diff --git a/packages/w32/alpc.go b/packages/w32/alpc.go
new file mode 100644
index 00000000..408d47ed
--- /dev/null
+++ b/packages/w32/alpc.go
@@ -0,0 +1,304 @@
+// Copyright 2010-2012 The W32 Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package w32
+
+import (
+	"fmt"
+	// "github.com/davecgh/go-spew/spew"
+	"syscall"
+	"unsafe"
+)
+
+var (
+	modntdll = syscall.NewLazyDLL("ntdll.dll")
+
+	procAlpcGetMessageAttribute          = modntdll.NewProc("AlpcGetMessageAttribute")
+	procNtAlpcAcceptConnectPort          = modntdll.NewProc("NtAlpcAcceptConnectPort")
+	procNtAlpcCancelMessage              = modntdll.NewProc("NtAlpcCancelMessage")
+	procNtAlpcConnectPort                = modntdll.NewProc("NtAlpcConnectPort")
+	procNtAlpcCreatePort                 = modntdll.NewProc("NtAlpcCreatePort")
+	procNtAlpcDisconnectPort             = modntdll.NewProc("NtAlpcDisconnectPort")
+	procNtAlpcSendWaitReceivePort        = modntdll.NewProc("NtAlpcSendWaitReceivePort")
+	procRtlCreateUnicodeStringFromAsciiz = modntdll.NewProc("RtlCreateUnicodeStringFromAsciiz")
+)
+
+//func RtlCreateUnicodeStringFromAsciiz(s string) (us UNICODE_STRING, e error) {
+//
+//	cs := C.CString(s)
+//	defer C.free(unsafe.Pointer(cs))
+//
+//	ret, _, lastErr := procRtlCreateUnicodeStringFromAsciiz.Call(
+//		uintptr(unsafe.Pointer(&us)),
+//		uintptr(unsafe.Pointer(cs)),
+//	)
+//
+//	if ret != 1 { // ret is a BOOL ( I think )
+//		e = lastErr
+//	}
+//
+//	return
+//}
+
+//func newUnicodeString(s string) (us UNICODE_STRING, e error) {
+//	// TODO probably not the most efficient way to do this, but I couldn't
+//	// work out how to manually initialize the UNICODE_STRING struct in a way
+//	// that the ALPC subsystem liked.
+//	us, e = RtlCreateUnicodeStringFromAsciiz(s)
+//	return
+//}
+
+// (this is a macro)
+// VOID InitializeObjectAttributes(
+//   [out]           POBJECT_ATTRIBUTES InitializedAttributes,
+//   [in]            PUNICODE_STRING ObjectName,
+//   [in]            ULONG Attributes,
+//   [in]            HANDLE RootDirectory,
+//   [in, optional]  PSECURITY_DESCRIPTOR SecurityDescriptor
+// )
+//func InitializeObjectAttributes(
+//	name string,
+//	attributes uint32,
+//	rootDir HANDLE,
+//	pSecurityDescriptor *SECURITY_DESCRIPTOR,
+//) (oa OBJECT_ATTRIBUTES, e error) {
+//
+//	oa = OBJECT_ATTRIBUTES{
+//		RootDirectory:      rootDir,
+//		Attributes:         attributes,
+//		SecurityDescriptor: pSecurityDescriptor,
+//	}
+//	oa.Length = uint32(unsafe.Sizeof(oa))
+//
+//	if len(name) > 0 {
+//		us, err := newUnicodeString(name)
+//		if err != nil {
+//			e = err
+//			return
+//		}
+//		oa.ObjectName = &us
+//	}
+//
+//	return
+//}
+
+// NTSTATUS
+// NtAlpcCreatePort(
+//   __out PHANDLE PortHandle,
+//   __in POBJECT_ATTRIBUTES ObjectAttributes,
+//   __in_opt PALPC_PORT_ATTRIBUTES PortAttributes
+//   );
+func NtAlpcCreatePort(pObjectAttributes *OBJECT_ATTRIBUTES, pPortAttributes *ALPC_PORT_ATTRIBUTES) (hPort HANDLE, e error) {
+
+	ret, _, _ := procNtAlpcCreatePort.Call(
+		uintptr(unsafe.Pointer(&hPort)),
+		uintptr(unsafe.Pointer(pObjectAttributes)),
+		uintptr(unsafe.Pointer(pPortAttributes)),
+	)
+
+	if ret != ERROR_SUCCESS {
+		return hPort, fmt.Errorf("0x%x", ret)
+	}
+
+	return
+}
+
+// NTSTATUS
+// NtAlpcConnectPort(
+//     __out PHANDLE PortHandle,
+//     __in PUNICODE_STRING PortName,
+//     __in POBJECT_ATTRIBUTES ObjectAttributes,
+//     __in_opt PALPC_PORT_ATTRIBUTES PortAttributes,
+//     __in ULONG Flags,
+//     __in_opt PSID RequiredServerSid,
+//     __inout PPORT_MESSAGE ConnectionMessage,
+//     __inout_opt PULONG BufferLength,
+//     __inout_opt PALPC_MESSAGE_ATTRIBUTES OutMessageAttributes,
+//     __inout_opt PALPC_MESSAGE_ATTRIBUTES InMessageAttributes,
+//     __in_opt PLARGE_INTEGER Timeout
+//     );
+//func NtAlpcConnectPort(
+//	destPort string,
+//	pClientObjAttrs *OBJECT_ATTRIBUTES,
+//	pClientAlpcPortAttrs *ALPC_PORT_ATTRIBUTES,
+//	flags uint32,
+//	pRequiredServerSid *SID,
+//	pConnMsg *AlpcShortMessage,
+//	pBufLen *uint32,
+//	pOutMsgAttrs *ALPC_MESSAGE_ATTRIBUTES,
+//	pInMsgAttrs *ALPC_MESSAGE_ATTRIBUTES,
+//	timeout *int64,
+//) (hPort HANDLE, e error) {
+//
+//	destPortU, e := newUnicodeString(destPort)
+//	if e != nil {
+//		return
+//	}
+//
+//	ret, _, _ := procNtAlpcConnectPort.Call(
+//		uintptr(unsafe.Pointer(&hPort)),
+//		uintptr(unsafe.Pointer(&destPortU)),
+//		uintptr(unsafe.Pointer(pClientObjAttrs)),
+//		uintptr(unsafe.Pointer(pClientAlpcPortAttrs)),
+//		uintptr(flags),
+//		uintptr(unsafe.Pointer(pRequiredServerSid)),
+//		uintptr(unsafe.Pointer(pConnMsg)),
+//		uintptr(unsafe.Pointer(pBufLen)),
+//		uintptr(unsafe.Pointer(pOutMsgAttrs)),
+//		uintptr(unsafe.Pointer(pInMsgAttrs)),
+//		uintptr(unsafe.Pointer(timeout)),
+//	)
+//
+//	if ret != ERROR_SUCCESS {
+//		e = fmt.Errorf("0x%x", ret)
+//	}
+//	return
+//}
+
+// NTSTATUS
+// NtAlpcAcceptConnectPort(
+//     __out PHANDLE PortHandle,
+//     __in HANDLE ConnectionPortHandle,
+//     __in ULONG Flags,
+//     __in POBJECT_ATTRIBUTES ObjectAttributes,
+//     __in PALPC_PORT_ATTRIBUTES PortAttributes,
+//     __in_opt PVOID PortContext,
+//     __in PPORT_MESSAGE ConnectionRequest,
+//     __inout_opt PALPC_MESSAGE_ATTRIBUTES ConnectionMessageAttributes,
+//     __in BOOLEAN AcceptConnection
+//     );
+func NtAlpcAcceptConnectPort(
+	hSrvConnPort HANDLE,
+	flags uint32,
+	pObjAttr *OBJECT_ATTRIBUTES,
+	pPortAttr *ALPC_PORT_ATTRIBUTES,
+	pContext *AlpcPortContext,
+	pConnReq *AlpcShortMessage,
+	pConnMsgAttrs *ALPC_MESSAGE_ATTRIBUTES,
+	accept uintptr,
+) (hPort HANDLE, e error) {
+
+	ret, _, _ := procNtAlpcAcceptConnectPort.Call(
+		uintptr(unsafe.Pointer(&hPort)),
+		uintptr(hSrvConnPort),
+		uintptr(flags),
+		uintptr(unsafe.Pointer(pObjAttr)),
+		uintptr(unsafe.Pointer(pPortAttr)),
+		uintptr(unsafe.Pointer(pContext)),
+		uintptr(unsafe.Pointer(pConnReq)),
+		uintptr(unsafe.Pointer(pConnMsgAttrs)),
+		accept,
+	)
+
+	if ret != ERROR_SUCCESS {
+		e = fmt.Errorf("0x%x", ret)
+	}
+	return
+}
+
+// NTSTATUS
+// NtAlpcSendWaitReceivePort(
+//     __in HANDLE PortHandle,
+//     __in ULONG Flags,
+//     __in_opt PPORT_MESSAGE SendMessage,
+//     __in_opt PALPC_MESSAGE_ATTRIBUTES SendMessageAttributes,
+//     __inout_opt PPORT_MESSAGE ReceiveMessage,
+//     __inout_opt PULONG BufferLength,
+//     __inout_opt PALPC_MESSAGE_ATTRIBUTES ReceiveMessageAttributes,
+//     __in_opt PLARGE_INTEGER Timeout
+//     );
+func NtAlpcSendWaitReceivePort(
+	hPort HANDLE,
+	flags uint32,
+	sendMsg *AlpcShortMessage, // Should actually point to PORT_MESSAGE + payload
+	sendMsgAttrs *ALPC_MESSAGE_ATTRIBUTES,
+	recvMsg *AlpcShortMessage,
+	recvBufLen *uint32,
+	recvMsgAttrs *ALPC_MESSAGE_ATTRIBUTES,
+	timeout *int64, // use native int64
+) (e error) {
+
+	ret, _, _ := procNtAlpcSendWaitReceivePort.Call(
+		uintptr(hPort),
+		uintptr(flags),
+		uintptr(unsafe.Pointer(sendMsg)),
+		uintptr(unsafe.Pointer(sendMsgAttrs)),
+		uintptr(unsafe.Pointer(recvMsg)),
+		uintptr(unsafe.Pointer(recvBufLen)),
+		uintptr(unsafe.Pointer(recvMsgAttrs)),
+		uintptr(unsafe.Pointer(timeout)),
+	)
+
+	if ret != ERROR_SUCCESS {
+		e = fmt.Errorf("0x%x", ret)
+	}
+	return
+}
+
+// NTSYSAPI
+// PVOID
+// NTAPI
+// AlpcGetMessageAttribute(
+//     __in PALPC_MESSAGE_ATTRIBUTES Buffer,
+//     __in ULONG AttributeFlag
+//     );
+
+// This basically returns a pointer to the correct struct for whichever
+// message attribute you asked for. In Go terms, it returns unsafe.Pointer
+// which you should then cast. Example:
+
+// ptr := AlpcGetMessageAttribute(&recvMsgAttrs, ALPC_MESSAGE_CONTEXT_ATTRIBUTE)
+// if ptr != nil {
+//     context := (*ALPC_CONTEXT_ATTR)(ptr)
+// }
+func AlpcGetMessageAttribute(buf *ALPC_MESSAGE_ATTRIBUTES, attr uint32) unsafe.Pointer {
+
+	ret, _, _ := procAlpcGetMessageAttribute.Call(
+		uintptr(unsafe.Pointer(buf)),
+		uintptr(attr),
+	)
+	return unsafe.Pointer(ret)
+}
+
+// NTSYSCALLAPI
+// NTSTATUS
+// NTAPI
+// NtAlpcCancelMessage(
+//     __in HANDLE PortHandle,
+//     __in ULONG Flags,
+//     __in PALPC_CONTEXT_ATTR MessageContext
+//     );
+func NtAlpcCancelMessage(hPort HANDLE, flags uint32, pMsgContext *ALPC_CONTEXT_ATTR) (e error) {
+
+	ret, _, _ := procNtAlpcCancelMessage.Call(
+		uintptr(hPort),
+		uintptr(flags),
+		uintptr(unsafe.Pointer(pMsgContext)),
+	)
+
+	if ret != ERROR_SUCCESS {
+		e = fmt.Errorf("0x%x", ret)
+	}
+	return
+}
+
+// NTSYSCALLAPI
+// NTSTATUS
+// NTAPI
+// NtAlpcDisconnectPort(
+//     __in HANDLE PortHandle,
+//     __in ULONG Flags
+//     );
+func NtAlpcDisconnectPort(hPort HANDLE, flags uint32) (e error) {
+
+	ret, _, _ := procNtAlpcDisconnectPort.Call(
+		uintptr(hPort),
+		uintptr(flags),
+	)
+
+	if ret != ERROR_SUCCESS {
+		e = fmt.Errorf("0x%x", ret)
+	}
+	return
+}
diff --git a/packages/w32/alpc_constants.go b/packages/w32/alpc_constants.go
new file mode 100644
index 00000000..82d9d2ed
--- /dev/null
+++ b/packages/w32/alpc_constants.go
@@ -0,0 +1,64 @@
+package w32
+
+const (
+	ALPC_PORFLG_ALLOW_LPC_REQUESTS = 0x20000
+	ALPC_PORFLG_SYSTEM_PROCESS     = 0x100000
+	ALPC_PORFLG_WAITABLE_PORT      = 0x40000
+)
+
+const (
+	ALPC_MSGFLG_REPLY_MESSAGE   = 0x1
+	ALPC_MSGFLG_LPC_MODE        = 0x2     // ?
+	ALPC_MSGFLG_RELEASE_MESSAGE = 0x10000 // dbg
+	ALPC_MSGFLG_SYNC_REQUEST    = 0x20000 // dbg
+	ALPC_MSGFLG_WAIT_USER_MODE  = 0x100000
+	ALPC_MSGFLG_WAIT_ALERTABLE  = 0x200000
+	ALPC_MSGFLG_WOW64_CALL      = 0x80000000 // dbg
+)
+const (
+	ALPC_MESSAGE_SECURITY_ATTRIBUTE = 0x80000000
+	ALPC_MESSAGE_VIEW_ATTRIBUTE     = 0x40000000
+	ALPC_MESSAGE_CONTEXT_ATTRIBUTE  = 0x20000000
+	ALPC_MESSAGE_HANDLE_ATTRIBUTE   = 0x10000000
+)
+
+const (
+	OBJ_INHERIT          = 0x00000002
+	OBJ_PERMANENT        = 0x00000010
+	OBJ_EXCLUSIVE        = 0x00000020
+	OBJ_CASE_INSENSITIVE = 0x00000040
+	OBJ_OPENIF           = 0x00000080
+	OBJ_OPENLINK         = 0x00000100
+	OBJ_KERNEL_HANDLE    = 0x00000200
+)
+
+const (
+	LPC_REQUEST               = 1
+	LPC_REPLY                 = 2
+	LPC_DATAGRAM              = 3
+	LPC_LOST_REPLY            = 4
+	LPC_PORT_CLOSED           = 5
+	LPC_CLIENT_DIED           = 6
+	LPC_EXCEPTION             = 7
+	LPC_DEBUG_EVENT           = 8
+	LPC_ERROR_EVENT           = 9
+	LPC_CONNECTION_REQUEST    = 10
+	LPC_CONTINUATION_REQUIRED = 0x2000
+)
+
+const (
+	SecurityAnonymous      uint32 = 1
+	SecurityIdentification uint32 = 2
+	SecurityImpersonation  uint32 = 3
+	SecurityDelegation     uint32 = 4
+)
+
+const (
+	SECURITY_DYNAMIC_TRACKING byte = 1
+	SECURITY_STATIC_TRACKING  byte = 0
+)
+
+const (
+	ALPC_SYNC_OBJECT_TYPE   uint32 = 2
+	ALPC_THREAD_OBJECT_TYPE uint32 = 4
+)
diff --git a/packages/w32/alpc_typedef.go b/packages/w32/alpc_typedef.go
new file mode 100644
index 00000000..52b35c97
--- /dev/null
+++ b/packages/w32/alpc_typedef.go
@@ -0,0 +1,181 @@
+package w32
+
+import (
+	"errors"
+)
+
+// nt!_ALPC_MESSAGE_ATTRIBUTES
+//  +0x000 AllocatedAttributes : Uint4B
+//  +0x004 ValidAttributes  : Uint4B
+type ALPC_MESSAGE_ATTRIBUTES struct {
+	AllocatedAttributes uint32
+	ValidAttributes     uint32
+}
+
+type ALPC_CONTEXT_ATTR struct {
+	PortContext    *AlpcPortContext
+	MessageContext uintptr
+	Sequence       uint32
+	MessageId      uint32
+	CallbackId     uint32
+}
+
+type ALPC_HANDLE_ATTR struct {
+	Flags         uint32
+	Handle        HANDLE
+	ObjectType    uint32
+	DesiredAccess uint32
+}
+
+// nt!_CLIENT_ID
+//  +0x000 UniqueProcess    : Ptr64 Void
+//  +0x008 UniqueThread     : Ptr64 Void
+type CLIENT_ID struct {
+	UniqueProcess uintptr
+	UniqueThread  uintptr
+}
+
+// nt!_UNICODE_STRING
+//  +0x000 Length           : Uint2B
+//  +0x002 MaximumLength    : Uint2B
+//  +0x008 Buffer           : Ptr64 Uint2B
+type UNICODE_STRING struct {
+	Length        uint16
+	MaximumLength uint16
+	_             [4]byte // align to 0x08
+	Buffer        *uint16
+}
+
+// nt!_OBJECT_ATTRIBUTES
+//  +0x000 Length           : Uint4B
+//  +0x008 RootDirectory    : Ptr64 Void
+//  +0x010 ObjectName       : Ptr64 _UNICODE_STRING
+//  +0x018 Attributes       : Uint4B
+//  +0x020 SecurityDescriptor : Ptr64 Void
+//  +0x028 SecurityQualityOfService : Ptr64 Void
+type OBJECT_ATTRIBUTES struct {
+	Length                   uint32
+	_                        [4]byte // align to 0x08
+	RootDirectory            HANDLE
+	ObjectName               *UNICODE_STRING
+	Attributes               uint32
+	_                        [4]byte // align to 0x20
+	SecurityDescriptor       *SECURITY_DESCRIPTOR
+	SecurityQualityOfService *SECURITY_QUALITY_OF_SERVICE
+}
+
+// cf: http://j00ru.vexillium.org/?p=502 for legacy RPC
+// nt!_PORT_MESSAGE
+//    +0x000 u1               : <unnamed-tag>
+//    +0x004 u2               : <unnamed-tag>
+//    +0x008 ClientId         : _CLIENT_ID
+//    +0x008 DoNotUseThisField : Float
+//    +0x018 MessageId        : Uint4B
+//    +0x020 ClientViewSize   : Uint8B
+//    +0x020 CallbackId       : Uint4B
+type PORT_MESSAGE struct {
+	DataLength     uint16 // These are the two unnamed unions
+	TotalLength    uint16 // without Length and ZeroInit
+	Type           uint16
+	DataInfoOffset uint16
+	ClientId       CLIENT_ID
+	MessageId      uint32
+	_              [4]byte // align up to 0x20
+	ClientViewSize uint64
+}
+
+func (pm PORT_MESSAGE) CallbackId() uint32 {
+	return uint32(pm.ClientViewSize >> 32)
+}
+
+func (pm PORT_MESSAGE) DoNotUseThisField() float64 {
+	panic("WE TOLD YOU NOT TO USE THIS FIELD")
+}
+
+const PORT_MESSAGE_SIZE = 0x28
+
+// http://www.nirsoft.net/kernel_struct/vista/SECURITY_QUALITY_OF_SERVICE.html
+type SECURITY_QUALITY_OF_SERVICE struct {
+	Length              uint32
+	ImpersonationLevel  uint32
+	ContextTrackingMode byte
+	EffectiveOnly       byte
+	_                   [2]byte // align to 12 bytes
+}
+
+const SECURITY_QOS_SIZE = 12
+
+// nt!_ALPC_PORT_ATTRIBUTES
+//  +0x000 Flags            : Uint4B
+//  +0x004 SecurityQos      : _SECURITY_QUALITY_OF_SERVICE
+//  +0x010 MaxMessageLength : Uint8B
+//  +0x018 MemoryBandwidth  : Uint8B
+//  +0x020 MaxPoolUsage     : Uint8B
+//  +0x028 MaxSectionSize   : Uint8B
+//  +0x030 MaxViewSize      : Uint8B
+//  +0x038 MaxTotalSectionSize : Uint8B
+//  +0x040 DupObjectTypes   : Uint4B
+//  +0x044 Reserved         : Uint4B
+type ALPC_PORT_ATTRIBUTES struct {
+	Flags               uint32
+	SecurityQos         SECURITY_QUALITY_OF_SERVICE
+	MaxMessageLength    uint64 // must be filled out
+	MemoryBandwidth     uint64
+	MaxPoolUsage        uint64
+	MaxSectionSize      uint64
+	MaxViewSize         uint64
+	MaxTotalSectionSize uint64
+	DupObjectTypes      uint32
+	Reserved            uint32
+}
+
+const SHORT_MESSAGE_MAX_SIZE uint16 = 65535 // MAX_USHORT
+const SHORT_MESSAGE_MAX_PAYLOAD uint16 = SHORT_MESSAGE_MAX_SIZE - PORT_MESSAGE_SIZE
+
+// LPC uses the first 4 bytes of the payload as an LPC Command, but this is
+// NOT represented here, to allow the use of raw ALPC. For legacy LPC, callers
+// must include the command as part of their payload.
+type AlpcShortMessage struct {
+	PORT_MESSAGE
+	Data [SHORT_MESSAGE_MAX_PAYLOAD]byte
+}
+
+func NewAlpcShortMessage() AlpcShortMessage {
+	sm := AlpcShortMessage{}
+	sm.TotalLength = SHORT_MESSAGE_MAX_SIZE
+	return sm
+}
+
+func (sm *AlpcShortMessage) SetData(d []byte) (e error) {
+
+	copy(sm.Data[:], d)
+	if len(d) > int(SHORT_MESSAGE_MAX_PAYLOAD) {
+		e = errors.New("data too big - truncated")
+		sm.DataLength = SHORT_MESSAGE_MAX_PAYLOAD
+		sm.TotalLength = SHORT_MESSAGE_MAX_SIZE
+		return
+	}
+	sm.TotalLength = uint16(PORT_MESSAGE_SIZE + len(d))
+	sm.DataLength = uint16(len(d))
+	return
+
+}
+
+// TODO - is this still useful?
+func (sm *AlpcShortMessage) GetData() []byte {
+	if int(sm.DataLength) > int(SHORT_MESSAGE_MAX_PAYLOAD) {
+		return sm.Data[:] // truncate
+	}
+	return sm.Data[:sm.DataLength]
+}
+
+func (sm *AlpcShortMessage) Reset() {
+	// zero the PORT_MESSAGE header
+	sm.PORT_MESSAGE = PORT_MESSAGE{}
+	sm.TotalLength = SHORT_MESSAGE_MAX_SIZE
+	sm.DataLength = 0
+}
+
+type AlpcPortContext struct {
+	Handle HANDLE
+}
diff --git a/packages/w32/comctl32.go b/packages/w32/comctl32.go
new file mode 100644
index 00000000..4f4e6b53
--- /dev/null
+++ b/packages/w32/comctl32.go
@@ -0,0 +1,109 @@
+// Copyright 2010-2012 The W32 Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package w32
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+var (
+	modcomctl32 = syscall.NewLazyDLL("comctl32.dll")
+
+	procInitCommonControlsEx    = modcomctl32.NewProc("InitCommonControlsEx")
+	procImageList_Create        = modcomctl32.NewProc("ImageList_Create")
+	procImageList_Destroy       = modcomctl32.NewProc("ImageList_Destroy")
+	procImageList_GetImageCount = modcomctl32.NewProc("ImageList_GetImageCount")
+	procImageList_SetImageCount = modcomctl32.NewProc("ImageList_SetImageCount")
+	procImageList_Add           = modcomctl32.NewProc("ImageList_Add")
+	procImageList_ReplaceIcon   = modcomctl32.NewProc("ImageList_ReplaceIcon")
+	procImageList_Remove        = modcomctl32.NewProc("ImageList_Remove")
+	procTrackMouseEvent         = modcomctl32.NewProc("_TrackMouseEvent")
+)
+
+func InitCommonControlsEx(lpInitCtrls *INITCOMMONCONTROLSEX) bool {
+	ret, _, _ := procInitCommonControlsEx.Call(
+		uintptr(unsafe.Pointer(lpInitCtrls)))
+
+	return ret != 0
+}
+
+func ImageList_Create(cx, cy int, flags uint, cInitial, cGrow int) HIMAGELIST {
+	ret, _, _ := procImageList_Create.Call(
+		uintptr(cx),
+		uintptr(cy),
+		uintptr(flags),
+		uintptr(cInitial),
+		uintptr(cGrow))
+
+	if ret == 0 {
+		panic("Create image list failed")
+	}
+
+	return HIMAGELIST(ret)
+}
+
+func ImageList_Destroy(himl HIMAGELIST) bool {
+	ret, _, _ := procImageList_Destroy.Call(
+		uintptr(himl))
+
+	return ret != 0
+}
+
+func ImageList_GetImageCount(himl HIMAGELIST) int {
+	ret, _, _ := procImageList_GetImageCount.Call(
+		uintptr(himl))
+
+	return int(ret)
+}
+
+func ImageList_SetImageCount(himl HIMAGELIST, uNewCount uint) bool {
+	ret, _, _ := procImageList_SetImageCount.Call(
+		uintptr(himl),
+		uintptr(uNewCount))
+
+	return ret != 0
+}
+
+func ImageList_Add(himl HIMAGELIST, hbmImage, hbmMask HBITMAP) int {
+	ret, _, _ := procImageList_Add.Call(
+		uintptr(himl),
+		uintptr(hbmImage),
+		uintptr(hbmMask))
+
+	return int(ret)
+}
+
+func ImageList_ReplaceIcon(himl HIMAGELIST, i int, hicon HICON) int {
+	ret, _, _ := procImageList_ReplaceIcon.Call(
+		uintptr(himl),
+		uintptr(i),
+		uintptr(hicon))
+
+	return int(ret)
+}
+
+func ImageList_AddIcon(himl HIMAGELIST, hicon HICON) int {
+	return ImageList_ReplaceIcon(himl, -1, hicon)
+}
+
+func ImageList_Remove(himl HIMAGELIST, i int) bool {
+	ret, _, _ := procImageList_Remove.Call(
+		uintptr(himl),
+		uintptr(i))
+
+	return ret != 0
+}
+
+func ImageList_RemoveAll(himl HIMAGELIST) bool {
+	return ImageList_Remove(himl, -1)
+}
+
+func TrackMouseEvent(tme *TRACKMOUSEEVENT) bool {
+	ret, _, _ := procTrackMouseEvent.Call(
+		uintptr(unsafe.Pointer(tme)))
+
+	return ret != 0
+}
diff --git a/packages/w32/comdlg32.go b/packages/w32/comdlg32.go
new file mode 100644
index 00000000..37bc9858
--- /dev/null
+++ b/packages/w32/comdlg32.go
@@ -0,0 +1,38 @@
+// Copyright 2010-2012 The W32 Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package w32
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+var (
+	modcomdlg32 = syscall.NewLazyDLL("comdlg32.dll")
+
+	procGetSaveFileName      = modcomdlg32.NewProc("GetSaveFileNameW")
+	procGetOpenFileName      = modcomdlg32.NewProc("GetOpenFileNameW")
+	procCommDlgExtendedError = modcomdlg32.NewProc("CommDlgExtendedError")
+)
+
+func GetOpenFileName(ofn *OPENFILENAME) bool {
+	ret, _, _ := procGetOpenFileName.Call(
+		uintptr(unsafe.Pointer(ofn)))
+
+	return ret != 0
+}
+
+func GetSaveFileName(ofn *OPENFILENAME) bool {
+	ret, _, _ := procGetSaveFileName.Call(
+		uintptr(unsafe.Pointer(ofn)))
+
+	return ret != 0
+}
+
+func CommDlgExtendedError() uint {
+	ret, _, _ := procCommDlgExtendedError.Call()
+
+	return uint(ret)
+}
diff --git a/packages/w32/constants.go b/packages/w32/constants.go
new file mode 100644
index 00000000..1775ca83
--- /dev/null
+++ b/packages/w32/constants.go
@@ -0,0 +1,2628 @@
+// Copyright 2010-2012 The W32 Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package w32
+
+const (
+	FALSE = 0
+	TRUE  = 1
+)
+
+const (
+	NO_ERROR                         = 0
+	ERROR_SUCCESS                    = 0
+	ERROR_FILE_NOT_FOUND             = 2
+	ERROR_PATH_NOT_FOUND             = 3
+	ERROR_ACCESS_DENIED              = 5
+	ERROR_INVALID_HANDLE             = 6
+	ERROR_BAD_FORMAT                 = 11
+	ERROR_INVALID_NAME               = 123
+	ERROR_MORE_DATA                  = 234
+	ERROR_NO_MORE_ITEMS              = 259
+	ERROR_INVALID_SERVICE_CONTROL    = 1052
+	ERROR_SERVICE_REQUEST_TIMEOUT    = 1053
+	ERROR_SERVICE_NO_THREAD          = 1054
+	ERROR_SERVICE_DATABASE_LOCKED    = 1055
+	ERROR_SERVICE_ALREADY_RUNNING    = 1056
+	ERROR_SERVICE_DISABLED           = 1058
+	ERROR_SERVICE_DOES_NOT_EXIST     = 1060
+	ERROR_SERVICE_CANNOT_ACCEPT_CTRL = 1061
+	ERROR_SERVICE_NOT_ACTIVE         = 1062
+	ERROR_DATABASE_DOES_NOT_EXIST    = 1065
+	ERROR_SERVICE_DEPENDENCY_FAIL    = 1068
+	ERROR_SERVICE_LOGON_FAILED       = 1069
+	ERROR_SERVICE_MARKED_FOR_DELETE  = 1072
+	ERROR_SERVICE_DEPENDENCY_DELETED = 1075
+)
+
+const (
+	SE_ERR_FNF             = 2
+	SE_ERR_PNF             = 3
+	SE_ERR_ACCESSDENIED    = 5
+	SE_ERR_OOM             = 8
+	SE_ERR_DLLNOTFOUND     = 32
+	SE_ERR_SHARE           = 26
+	SE_ERR_ASSOCINCOMPLETE = 27
+	SE_ERR_DDETIMEOUT      = 28
+	SE_ERR_DDEFAIL         = 29
+	SE_ERR_DDEBUSY         = 30
+	SE_ERR_NOASSOC         = 31
+)
+
+const (
+	CW_USEDEFAULT = ^0x7fffffff
+)
+
+// ShowWindow constants
+const (
+	SW_HIDE            = 0
+	SW_NORMAL          = 1
+	SW_SHOWNORMAL      = 1
+	SW_SHOWMINIMIZED   = 2
+	SW_MAXIMIZE        = 3
+	SW_SHOWMAXIMIZED   = 3
+	SW_SHOWNOACTIVATE  = 4
+	SW_SHOW            = 5
+	SW_MINIMIZE        = 6
+	SW_SHOWMINNOACTIVE = 7
+	SW_SHOWNA          = 8
+	SW_RESTORE         = 9
+	SW_SHOWDEFAULT     = 10
+	SW_FORCEMINIMIZE   = 11
+)
+
+// Window class styles
+const (
+	CS_VREDRAW         = 0x00000001
+	CS_HREDRAW         = 0x00000002
+	CS_KEYCVTWINDOW    = 0x00000004
+	CS_DBLCLKS         = 0x00000008
+	CS_OWNDC           = 0x00000020
+	CS_CLASSDC         = 0x00000040
+	CS_PARENTDC        = 0x00000080
+	CS_NOKEYCVT        = 0x00000100
+	CS_NOCLOSE         = 0x00000200
+	CS_SAVEBITS        = 0x00000800
+	CS_BYTEALIGNCLIENT = 0x00001000
+	CS_BYTEALIGNWINDOW = 0x00002000
+	CS_GLOBALCLASS     = 0x00004000
+	CS_IME             = 0x00010000
+	CS_DROPSHADOW      = 0x00020000
+)
+
+// Predefined cursor constants
+const (
+	IDC_ARROW       = 32512
+	IDC_IBEAM       = 32513
+	IDC_WAIT        = 32514
+	IDC_CROSS       = 32515
+	IDC_UPARROW     = 32516
+	IDC_SIZENWSE    = 32642
+	IDC_SIZENESW    = 32643
+	IDC_SIZEWE      = 32644
+	IDC_SIZENS      = 32645
+	IDC_SIZEALL     = 32646
+	IDC_NO          = 32648
+	IDC_HAND        = 32649
+	IDC_APPSTARTING = 32650
+	IDC_HELP        = 32651
+	IDC_ICON        = 32641
+	IDC_SIZE        = 32640
+)
+
+// Predefined icon constants
+const (
+	IDI_APPLICATION = 32512
+	IDI_HAND        = 32513
+	IDI_QUESTION    = 32514
+	IDI_EXCLAMATION = 32515
+	IDI_ASTERISK    = 32516
+	IDI_WINLOGO     = 32517
+	IDI_WARNING     = IDI_EXCLAMATION
+	IDI_ERROR       = IDI_HAND
+	IDI_INFORMATION = IDI_ASTERISK
+)
+
+// Button style constants
+const (
+	BS_3STATE          = 5
+	BS_AUTO3STATE      = 6
+	BS_AUTOCHECKBOX    = 3
+	BS_AUTORADIOBUTTON = 9
+	BS_BITMAP          = 128
+	BS_BOTTOM          = 0X800
+	BS_CENTER          = 0X300
+	BS_CHECKBOX        = 2
+	BS_DEFPUSHBUTTON   = 1
+	BS_GROUPBOX        = 7
+	BS_ICON            = 64
+	BS_LEFT            = 256
+	BS_LEFTTEXT        = 32
+	BS_MULTILINE       = 0X2000
+	BS_NOTIFY          = 0X4000
+	BS_OWNERDRAW       = 0XB
+	BS_PUSHBUTTON      = 0
+	BS_PUSHLIKE        = 4096
+	BS_RADIOBUTTON     = 4
+	BS_RIGHT           = 512
+	BS_RIGHTBUTTON     = 32
+	BS_TEXT            = 0
+	BS_TOP             = 0X400
+	BS_USERBUTTON      = 8
+	BS_VCENTER         = 0XC00
+	BS_FLAT            = 0X8000
+)
+
+// Button state constants
+const (
+	BST_CHECKED       = 1
+	BST_INDETERMINATE = 2
+	BST_UNCHECKED     = 0
+	BST_FOCUS         = 8
+	BST_PUSHED        = 4
+)
+
+// Predefined brushes constants
+const (
+	COLOR_3DDKSHADOW              = 21
+	COLOR_3DFACE                  = 15
+	COLOR_3DHILIGHT               = 20
+	COLOR_3DHIGHLIGHT             = 20
+	COLOR_3DLIGHT                 = 22
+	COLOR_BTNHILIGHT              = 20
+	COLOR_3DSHADOW                = 16
+	COLOR_ACTIVEBORDER            = 10
+	COLOR_ACTIVECAPTION           = 2
+	COLOR_APPWORKSPACE            = 12
+	COLOR_BACKGROUND              = 1
+	COLOR_DESKTOP                 = 1
+	COLOR_BTNFACE                 = 15
+	COLOR_BTNHIGHLIGHT            = 20
+	COLOR_BTNSHADOW               = 16
+	COLOR_BTNTEXT                 = 18
+	COLOR_CAPTIONTEXT             = 9
+	COLOR_GRAYTEXT                = 17
+	COLOR_HIGHLIGHT               = 13
+	COLOR_HIGHLIGHTTEXT           = 14
+	COLOR_INACTIVEBORDER          = 11
+	COLOR_INACTIVECAPTION         = 3
+	COLOR_INACTIVECAPTIONTEXT     = 19
+	COLOR_INFOBK                  = 24
+	COLOR_INFOTEXT                = 23
+	COLOR_MENU                    = 4
+	COLOR_MENUTEXT                = 7
+	COLOR_SCROLLBAR               = 0
+	COLOR_WINDOW                  = 5
+	COLOR_WINDOWFRAME             = 6
+	COLOR_WINDOWTEXT              = 8
+	COLOR_HOTLIGHT                = 26
+	COLOR_GRADIENTACTIVECAPTION   = 27
+	COLOR_GRADIENTINACTIVECAPTION = 28
+)
+
+// Button message constants
+const (
+	BM_CLICK    = 245
+	BM_GETCHECK = 240
+	BM_GETIMAGE = 246
+	BM_GETSTATE = 242
+	BM_SETCHECK = 241
+	BM_SETIMAGE = 247
+	BM_SETSTATE = 243
+	BM_SETSTYLE = 244
+)
+
+// Button notifications
+const (
+	BN_CLICKED       = 0
+	BN_PAINT         = 1
+	BN_HILITE        = 2
+	BN_PUSHED        = BN_HILITE
+	BN_UNHILITE      = 3
+	BN_UNPUSHED      = BN_UNHILITE
+	BN_DISABLE       = 4
+	BN_DOUBLECLICKED = 5
+	BN_DBLCLK        = BN_DOUBLECLICKED
+	BN_SETFOCUS      = 6
+	BN_KILLFOCUS     = 7
+)
+
+// GetWindowLong and GetWindowLongPtr constants
+const (
+	GWL_EXSTYLE     = -20
+	GWL_STYLE       = -16
+	GWL_WNDPROC     = -4
+	GWLP_WNDPROC    = -4
+	GWL_HINSTANCE   = -6
+	GWLP_HINSTANCE  = -6
+	GWL_HWNDPARENT  = -8
+	GWLP_HWNDPARENT = -8
+	GWL_ID          = -12
+	GWLP_ID         = -12
+	GWL_USERDATA    = -21
+	GWLP_USERDATA   = -21
+)
+
+// Window style constants
+const (
+	WS_OVERLAPPED       = 0X00000000
+	WS_POPUP            = 0X80000000
+	WS_CHILD            = 0X40000000
+	WS_MINIMIZE         = 0X20000000
+	WS_VISIBLE          = 0X10000000
+	WS_DISABLED         = 0X08000000
+	WS_CLIPSIBLINGS     = 0X04000000
+	WS_CLIPCHILDREN     = 0X02000000
+	WS_MAXIMIZE         = 0X01000000
+	WS_CAPTION          = 0X00C00000
+	WS_BORDER           = 0X00800000
+	WS_DLGFRAME         = 0X00400000
+	WS_VSCROLL          = 0X00200000
+	WS_HSCROLL          = 0X00100000
+	WS_SYSMENU          = 0X00080000
+	WS_THICKFRAME       = 0X00040000
+	WS_GROUP            = 0X00020000
+	WS_TABSTOP          = 0X00010000
+	WS_MINIMIZEBOX      = 0X00020000
+	WS_MAXIMIZEBOX      = 0X00010000
+	WS_TILED            = 0X00000000
+	WS_ICONIC           = 0X20000000
+	WS_SIZEBOX          = 0X00040000
+	WS_OVERLAPPEDWINDOW = 0X00000000 | 0X00C00000 | 0X00080000 | 0X00040000 | 0X00020000 | 0X00010000
+	WS_POPUPWINDOW      = 0X80000000 | 0X00800000 | 0X00080000
+	WS_CHILDWINDOW      = 0X40000000
+)
+
+// Extended window style constants
+const (
+	WS_EX_DLGMODALFRAME    = 0X00000001
+	WS_EX_NOPARENTNOTIFY   = 0X00000004
+	WS_EX_TOPMOST          = 0X00000008
+	WS_EX_ACCEPTFILES      = 0X00000010
+	WS_EX_TRANSPARENT      = 0X00000020
+	WS_EX_MDICHILD         = 0X00000040
+	WS_EX_TOOLWINDOW       = 0X00000080
+	WS_EX_WINDOWEDGE       = 0X00000100
+	WS_EX_CLIENTEDGE       = 0X00000200
+	WS_EX_CONTEXTHELP      = 0X00000400
+	WS_EX_RIGHT            = 0X00001000
+	WS_EX_LEFT             = 0X00000000
+	WS_EX_RTLREADING       = 0X00002000
+	WS_EX_LTRREADING       = 0X00000000
+	WS_EX_LEFTSCROLLBAR    = 0X00004000
+	WS_EX_RIGHTSCROLLBAR   = 0X00000000
+	WS_EX_CONTROLPARENT    = 0X00010000
+	WS_EX_STATICEDGE       = 0X00020000
+	WS_EX_APPWINDOW        = 0X00040000
+	WS_EX_OVERLAPPEDWINDOW = 0X00000100 | 0X00000200
+	WS_EX_PALETTEWINDOW    = 0X00000100 | 0X00000080 | 0X00000008
+	WS_EX_LAYERED          = 0X00080000
+	WS_EX_NOINHERITLAYOUT  = 0X00100000
+	WS_EX_LAYOUTRTL        = 0X00400000
+	WS_EX_NOACTIVATE       = 0X08000000
+)
+
+// Window message constants
+const (
+	WM_APP                    = 32768
+	WM_ACTIVATE               = 6
+	WM_ACTIVATEAPP            = 28
+	WM_AFXFIRST               = 864
+	WM_AFXLAST                = 895
+	WM_ASKCBFORMATNAME        = 780
+	WM_CANCELJOURNAL          = 75
+	WM_CANCELMODE             = 31
+	WM_CAPTURECHANGED         = 533
+	WM_CHANGECBCHAIN          = 781
+	WM_CHAR                   = 258
+	WM_CHARTOITEM             = 47
+	WM_CHILDACTIVATE          = 34
+	WM_CLEAR                  = 771
+	WM_CLOSE                  = 16
+	WM_COMMAND                = 273
+	WM_COMMNOTIFY             = 68 /* OBSOLETE */
+	WM_COMPACTING             = 65
+	WM_COMPAREITEM            = 57
+	WM_CONTEXTMENU            = 123
+	WM_COPY                   = 769
+	WM_COPYDATA               = 74
+	WM_CREATE                 = 1
+	WM_CTLCOLORBTN            = 309
+	WM_CTLCOLORDLG            = 310
+	WM_CTLCOLOREDIT           = 307
+	WM_CTLCOLORLISTBOX        = 308
+	WM_CTLCOLORMSGBOX         = 306
+	WM_CTLCOLORSCROLLBAR      = 311
+	WM_CTLCOLORSTATIC         = 312
+	WM_CUT                    = 768
+	WM_DEADCHAR               = 259
+	WM_DELETEITEM             = 45
+	WM_DESTROY                = 2
+	WM_DESTROYCLIPBOARD       = 775
+	WM_DEVICECHANGE           = 537
+	WM_DEVMODECHANGE          = 27
+	WM_DISPLAYCHANGE          = 126
+	WM_DRAWCLIPBOARD          = 776
+	WM_DRAWITEM               = 43
+	WM_DROPFILES              = 563
+	WM_ENABLE                 = 10
+	WM_ENDSESSION             = 22
+	WM_ENTERIDLE              = 289
+	WM_ENTERMENULOOP          = 529
+	WM_ENTERSIZEMOVE          = 561
+	WM_ERASEBKGND             = 20
+	WM_EXITMENULOOP           = 530
+	WM_EXITSIZEMOVE           = 562
+	WM_FONTCHANGE             = 29
+	WM_GETDLGCODE             = 135
+	WM_GETFONT                = 49
+	WM_GETHOTKEY              = 51
+	WM_GETICON                = 127
+	WM_GETMINMAXINFO          = 36
+	WM_GETTEXT                = 13
+	WM_GETTEXTLENGTH          = 14
+	WM_HANDHELDFIRST          = 856
+	WM_HANDHELDLAST           = 863
+	WM_HELP                   = 83
+	WM_HOTKEY                 = 786
+	WM_HSCROLL                = 276
+	WM_HSCROLLCLIPBOARD       = 782
+	WM_ICONERASEBKGND         = 39
+	WM_INITDIALOG             = 272
+	WM_INITMENU               = 278
+	WM_INITMENUPOPUP          = 279
+	WM_INPUT                  = 0X00FF
+	WM_INPUTLANGCHANGE        = 81
+	WM_INPUTLANGCHANGEREQUEST = 80
+	WM_KEYDOWN                = 256
+	WM_KEYUP                  = 257
+	WM_KILLFOCUS              = 8
+	WM_MDIACTIVATE            = 546
+	WM_MDICASCADE             = 551
+	WM_MDICREATE              = 544
+	WM_MDIDESTROY             = 545
+	WM_MDIGETACTIVE           = 553
+	WM_MDIICONARRANGE         = 552
+	WM_MDIMAXIMIZE            = 549
+	WM_MDINEXT                = 548
+	WM_MDIREFRESHMENU         = 564
+	WM_MDIRESTORE             = 547
+	WM_MDISETMENU             = 560
+	WM_MDITILE                = 550
+	WM_MEASUREITEM            = 44
+	WM_GETOBJECT              = 0X003D
+	WM_CHANGEUISTATE          = 0X0127
+	WM_UPDATEUISTATE          = 0X0128
+	WM_QUERYUISTATE           = 0X0129
+	WM_UNINITMENUPOPUP        = 0X0125
+	WM_MENURBUTTONUP          = 290
+	WM_MENUCOMMAND            = 0X0126
+	WM_MENUGETOBJECT          = 0X0124
+	WM_MENUDRAG               = 0X0123
+	WM_APPCOMMAND             = 0X0319
+	WM_MENUCHAR               = 288
+	WM_MENUSELECT             = 287
+	WM_MOVE                   = 3
+	WM_MOVING                 = 534
+	WM_NCACTIVATE             = 134
+	WM_NCCALCSIZE             = 131
+	WM_NCCREATE               = 129
+	WM_NCDESTROY              = 130
+	WM_NCHITTEST              = 132
+	WM_NCLBUTTONDBLCLK        = 163
+	WM_NCLBUTTONDOWN          = 161
+	WM_NCLBUTTONUP            = 162
+	WM_NCMBUTTONDBLCLK        = 169
+	WM_NCMBUTTONDOWN          = 167
+	WM_NCMBUTTONUP            = 168
+	WM_NCXBUTTONDOWN          = 171
+	WM_NCXBUTTONUP            = 172
+	WM_NCXBUTTONDBLCLK        = 173
+	WM_NCMOUSEHOVER           = 0X02A0
+	WM_NCMOUSELEAVE           = 0X02A2
+	WM_NCMOUSEMOVE            = 160
+	WM_NCPAINT                = 133
+	WM_NCRBUTTONDBLCLK        = 166
+	WM_NCRBUTTONDOWN          = 164
+	WM_NCRBUTTONUP            = 165
+	WM_NEXTDLGCTL             = 40
+	WM_NEXTMENU               = 531
+	WM_NOTIFY                 = 78
+	WM_NOTIFYFORMAT           = 85
+	WM_NULL                   = 0
+	WM_PAINT                  = 15
+	WM_PAINTCLIPBOARD         = 777
+	WM_PAINTICON              = 38
+	WM_PALETTECHANGED         = 785
+	WM_PALETTEISCHANGING      = 784
+	WM_PARENTNOTIFY           = 528
+	WM_PASTE                  = 770
+	WM_PENWINFIRST            = 896
+	WM_PENWINLAST             = 911
+	WM_POWER                  = 72
+	WM_POWERBROADCAST         = 536
+	WM_PRINT                  = 791
+	WM_PRINTCLIENT            = 792
+	WM_QUERYDRAGICON          = 55
+	WM_QUERYENDSESSION        = 17
+	WM_QUERYNEWPALETTE        = 783
+	WM_QUERYOPEN              = 19
+	WM_QUEUESYNC              = 35
+	WM_QUIT                   = 18
+	WM_RENDERALLFORMATS       = 774
+	WM_RENDERFORMAT           = 773
+	WM_SETCURSOR              = 32
+	WM_SETFOCUS               = 7
+	WM_SETFONT                = 48
+	WM_SETHOTKEY              = 50
+	WM_SETICON                = 128
+	WM_SETREDRAW              = 11
+	WM_SETTEXT                = 12
+	WM_SETTINGCHANGE          = 26
+	WM_SHOWWINDOW             = 24
+	WM_SIZE                   = 5
+	WM_SIZECLIPBOARD          = 779
+	WM_SIZING                 = 532
+	WM_SPOOLERSTATUS          = 42
+	WM_STYLECHANGED           = 125
+	WM_STYLECHANGING          = 124
+	WM_SYSCHAR                = 262
+	WM_SYSCOLORCHANGE         = 21
+	WM_SYSCOMMAND             = 274
+	WM_SYSDEADCHAR            = 263
+	WM_SYSKEYDOWN             = 260
+	WM_SYSKEYUP               = 261
+	WM_TCARD                  = 82
+	WM_THEMECHANGED           = 794
+	WM_TIMECHANGE             = 30
+	WM_TIMER                  = 275
+	WM_UNDO                   = 772
+	WM_USER                   = 1024
+	WM_USERCHANGED            = 84
+	WM_VKEYTOITEM             = 46
+	WM_VSCROLL                = 277
+	WM_VSCROLLCLIPBOARD       = 778
+	WM_WINDOWPOSCHANGED       = 71
+	WM_WINDOWPOSCHANGING      = 70
+	WM_WININICHANGE           = 26
+	WM_KEYFIRST               = 256
+	WM_KEYLAST                = 264
+	WM_SYNCPAINT              = 136
+	WM_MOUSEACTIVATE          = 33
+	WM_MOUSEMOVE              = 512
+	WM_LBUTTONDOWN            = 513
+	WM_LBUTTONUP              = 514
+	WM_LBUTTONDBLCLK          = 515
+	WM_RBUTTONDOWN            = 516
+	WM_RBUTTONUP              = 517
+	WM_RBUTTONDBLCLK          = 518
+	WM_MBUTTONDOWN            = 519
+	WM_MBUTTONUP              = 520
+	WM_MBUTTONDBLCLK          = 521
+	WM_MOUSEWHEEL             = 522
+	WM_XBUTTONDOWN            = 523
+	WM_XBUTTONUP              = 524
+	WM_XBUTTONDBLCLK          = 525
+	WM_MOUSEHWHEEL            = 526
+	WM_MOUSEFIRST             = 512
+	WM_MOUSELAST              = 526
+	WM_MOUSEHOVER             = 0X2A1
+	WM_MOUSELEAVE             = 0X2A3
+	WM_CLIPBOARDUPDATE        = 0x031D
+)
+
+// WM_ACTIVATE
+const (
+	WA_INACTIVE    = 0
+	WA_ACTIVE      = 1
+	WA_CLICKACTIVE = 2
+)
+
+const LF_FACESIZE = 32
+
+// Font weight constants
+const (
+	FW_DONTCARE   = 0
+	FW_THIN       = 100
+	FW_EXTRALIGHT = 200
+	FW_ULTRALIGHT = FW_EXTRALIGHT
+	FW_LIGHT      = 300
+	FW_NORMAL     = 400
+	FW_REGULAR    = 400
+	FW_MEDIUM     = 500
+	FW_SEMIBOLD   = 600
+	FW_DEMIBOLD   = FW_SEMIBOLD
+	FW_BOLD       = 700
+	FW_EXTRABOLD  = 800
+	FW_ULTRABOLD  = FW_EXTRABOLD
+	FW_HEAVY      = 900
+	FW_BLACK      = FW_HEAVY
+)
+
+// Charset constants
+const (
+	ANSI_CHARSET        = 0
+	DEFAULT_CHARSET     = 1
+	SYMBOL_CHARSET      = 2
+	SHIFTJIS_CHARSET    = 128
+	HANGEUL_CHARSET     = 129
+	HANGUL_CHARSET      = 129
+	GB2312_CHARSET      = 134
+	CHINESEBIG5_CHARSET = 136
+	GREEK_CHARSET       = 161
+	TURKISH_CHARSET     = 162
+	HEBREW_CHARSET      = 177
+	ARABIC_CHARSET      = 178
+	BALTIC_CHARSET      = 186
+	RUSSIAN_CHARSET     = 204
+	THAI_CHARSET        = 222
+	EASTEUROPE_CHARSET  = 238
+	OEM_CHARSET         = 255
+	JOHAB_CHARSET       = 130
+	VIETNAMESE_CHARSET  = 163
+	MAC_CHARSET         = 77
+)
+
+// Font output precision constants
+const (
+	OUT_DEFAULT_PRECIS   = 0
+	OUT_STRING_PRECIS    = 1
+	OUT_CHARACTER_PRECIS = 2
+	OUT_STROKE_PRECIS    = 3
+	OUT_TT_PRECIS        = 4
+	OUT_DEVICE_PRECIS    = 5
+	OUT_RASTER_PRECIS    = 6
+	OUT_TT_ONLY_PRECIS   = 7
+	OUT_OUTLINE_PRECIS   = 8
+	OUT_PS_ONLY_PRECIS   = 10
+)
+
+// Font clipping precision constants
+const (
+	CLIP_DEFAULT_PRECIS   = 0
+	CLIP_CHARACTER_PRECIS = 1
+	CLIP_STROKE_PRECIS    = 2
+	CLIP_MASK             = 15
+	CLIP_LH_ANGLES        = 16
+	CLIP_TT_ALWAYS        = 32
+	CLIP_EMBEDDED         = 128
+)
+
+// Font output quality constants
+const (
+	DEFAULT_QUALITY        = 0
+	DRAFT_QUALITY          = 1
+	PROOF_QUALITY          = 2
+	NONANTIALIASED_QUALITY = 3
+	ANTIALIASED_QUALITY    = 4
+	CLEARTYPE_QUALITY      = 5
+)
+
+// Font pitch constants
+const (
+	DEFAULT_PITCH  = 0
+	FIXED_PITCH    = 1
+	VARIABLE_PITCH = 2
+)
+
+// Font family constants
+const (
+	FF_DECORATIVE = 80
+	FF_DONTCARE   = 0
+	FF_MODERN     = 48
+	FF_ROMAN      = 16
+	FF_SCRIPT     = 64
+	FF_SWISS      = 32
+)
+
+// DeviceCapabilities capabilities
+const (
+	DC_FIELDS            = 1
+	DC_PAPERS            = 2
+	DC_PAPERSIZE         = 3
+	DC_MINEXTENT         = 4
+	DC_MAXEXTENT         = 5
+	DC_BINS              = 6
+	DC_DUPLEX            = 7
+	DC_SIZE              = 8
+	DC_EXTRA             = 9
+	DC_VERSION           = 10
+	DC_DRIVER            = 11
+	DC_BINNAMES          = 12
+	DC_ENUMRESOLUTIONS   = 13
+	DC_FILEDEPENDENCIES  = 14
+	DC_TRUETYPE          = 15
+	DC_PAPERNAMES        = 16
+	DC_ORIENTATION       = 17
+	DC_COPIES            = 18
+	DC_BINADJUST         = 19
+	DC_EMF_COMPLIANT     = 20
+	DC_DATATYPE_PRODUCED = 21
+	DC_COLLATE           = 22
+	DC_MANUFACTURER      = 23
+	DC_MODEL             = 24
+	DC_PERSONALITY       = 25
+	DC_PRINTRATE         = 26
+	DC_PRINTRATEUNIT     = 27
+	DC_PRINTERMEM        = 28
+	DC_MEDIAREADY        = 29
+	DC_STAPLE            = 30
+	DC_PRINTRATEPPM      = 31
+	DC_COLORDEVICE       = 32
+	DC_NUP               = 33
+	DC_MEDIATYPENAMES    = 34
+	DC_MEDIATYPES        = 35
+)
+
+// GetDeviceCaps index constants
+const (
+	DRIVERVERSION   = 0
+	TECHNOLOGY      = 2
+	HORZSIZE        = 4
+	VERTSIZE        = 6
+	HORZRES         = 8
+	VERTRES         = 10
+	LOGPIXELSX      = 88
+	LOGPIXELSY      = 90
+	BITSPIXEL       = 12
+	PLANES          = 14
+	NUMBRUSHES      = 16
+	NUMPENS         = 18
+	NUMFONTS        = 22
+	NUMCOLORS       = 24
+	NUMMARKERS      = 20
+	ASPECTX         = 40
+	ASPECTY         = 42
+	ASPECTXY        = 44
+	PDEVICESIZE     = 26
+	CLIPCAPS        = 36
+	SIZEPALETTE     = 104
+	NUMRESERVED     = 106
+	COLORRES        = 108
+	PHYSICALWIDTH   = 110
+	PHYSICALHEIGHT  = 111
+	PHYSICALOFFSETX = 112
+	PHYSICALOFFSETY = 113
+	SCALINGFACTORX  = 114
+	SCALINGFACTORY  = 115
+	VREFRESH        = 116
+	DESKTOPHORZRES  = 118
+	DESKTOPVERTRES  = 117
+	BLTALIGNMENT    = 119
+	SHADEBLENDCAPS  = 120
+	COLORMGMTCAPS   = 121
+	RASTERCAPS      = 38
+	CURVECAPS       = 28
+	LINECAPS        = 30
+	POLYGONALCAPS   = 32
+	TEXTCAPS        = 34
+)
+
+// GetDeviceCaps TECHNOLOGY constants
+const (
+	DT_PLOTTER    = 0
+	DT_RASDISPLAY = 1
+	DT_RASPRINTER = 2
+	DT_RASCAMERA  = 3
+	DT_CHARSTREAM = 4
+	DT_METAFILE   = 5
+	DT_DISPFILE   = 6
+)
+
+// GetDeviceCaps SHADEBLENDCAPS constants
+const (
+	SB_NONE          = 0x00
+	SB_CONST_ALPHA   = 0x01
+	SB_PIXEL_ALPHA   = 0x02
+	SB_PREMULT_ALPHA = 0x04
+	SB_GRAD_RECT     = 0x10
+	SB_GRAD_TRI      = 0x20
+)
+
+// GetDeviceCaps COLORMGMTCAPS constants
+const (
+	CM_NONE       = 0x00
+	CM_DEVICE_ICM = 0x01
+	CM_GAMMA_RAMP = 0x02
+	CM_CMYK_COLOR = 0x04
+)
+
+// GetDeviceCaps RASTERCAPS constants
+const (
+	RC_BANDING      = 2
+	RC_BITBLT       = 1
+	RC_BITMAP64     = 8
+	RC_DI_BITMAP    = 128
+	RC_DIBTODEV     = 512
+	RC_FLOODFILL    = 4096
+	RC_GDI20_OUTPUT = 16
+	RC_PALETTE      = 256
+	RC_SCALING      = 4
+	RC_STRETCHBLT   = 2048
+	RC_STRETCHDIB   = 8192
+	RC_DEVBITS      = 0x8000
+	RC_OP_DX_OUTPUT = 0x4000
+)
+
+// GetDeviceCaps CURVECAPS constants
+const (
+	CC_NONE       = 0
+	CC_CIRCLES    = 1
+	CC_PIE        = 2
+	CC_CHORD      = 4
+	CC_ELLIPSES   = 8
+	CC_WIDE       = 16
+	CC_STYLED     = 32
+	CC_WIDESTYLED = 64
+	CC_INTERIORS  = 128
+	CC_ROUNDRECT  = 256
+)
+
+// GetDeviceCaps LINECAPS constants
+const (
+	LC_NONE       = 0
+	LC_POLYLINE   = 2
+	LC_MARKER     = 4
+	LC_POLYMARKER = 8
+	LC_WIDE       = 16
+	LC_STYLED     = 32
+	LC_WIDESTYLED = 64
+	LC_INTERIORS  = 128
+)
+
+// GetDeviceCaps POLYGONALCAPS constants
+const (
+	PC_NONE        = 0
+	PC_POLYGON     = 1
+	PC_POLYPOLYGON = 256
+	PC_PATHS       = 512
+	PC_RECTANGLE   = 2
+	PC_WINDPOLYGON = 4
+	PC_SCANLINE    = 8
+	PC_TRAPEZOID   = 4
+	PC_WIDE        = 16
+	PC_STYLED      = 32
+	PC_WIDESTYLED  = 64
+	PC_INTERIORS   = 128
+)
+
+// GetDeviceCaps TEXTCAPS constants
+const (
+	TC_OP_CHARACTER = 1
+	TC_OP_STROKE    = 2
+	TC_CP_STROKE    = 4
+	TC_CR_90        = 8
+	TC_CR_ANY       = 16
+	TC_SF_X_YINDEP  = 32
+	TC_SA_DOUBLE    = 64
+	TC_SA_INTEGER   = 128
+	TC_SA_CONTIN    = 256
+	TC_EA_DOUBLE    = 512
+	TC_IA_ABLE      = 1024
+	TC_UA_ABLE      = 2048
+	TC_SO_ABLE      = 4096
+	TC_RA_ABLE      = 8192
+	TC_VA_ABLE      = 16384
+	TC_RESERVED     = 32768
+	TC_SCROLLBLT    = 65536
+)
+
+// Static control styles
+const (
+	SS_BITMAP          = 14
+	SS_BLACKFRAME      = 7
+	SS_BLACKRECT       = 4
+	SS_CENTER          = 1
+	SS_CENTERIMAGE     = 512
+	SS_EDITCONTROL     = 0x2000
+	SS_ENHMETAFILE     = 15
+	SS_ETCHEDFRAME     = 18
+	SS_ETCHEDHORZ      = 16
+	SS_ETCHEDVERT      = 17
+	SS_GRAYFRAME       = 8
+	SS_GRAYRECT        = 5
+	SS_ICON            = 3
+	SS_LEFT            = 0
+	SS_LEFTNOWORDWRAP  = 0xc
+	SS_NOPREFIX        = 128
+	SS_NOTIFY          = 256
+	SS_OWNERDRAW       = 0xd
+	SS_REALSIZECONTROL = 0x040
+	SS_REALSIZEIMAGE   = 0x800
+	SS_RIGHT           = 2
+	SS_RIGHTJUST       = 0x400
+	SS_SIMPLE          = 11
+	SS_SUNKEN          = 4096
+	SS_WHITEFRAME      = 9
+	SS_WHITERECT       = 6
+	SS_USERITEM        = 10
+	SS_TYPEMASK        = 0x0000001F
+	SS_ENDELLIPSIS     = 0x00004000
+	SS_PATHELLIPSIS    = 0x00008000
+	SS_WORDELLIPSIS    = 0x0000C000
+	SS_ELLIPSISMASK    = 0x0000C000
+)
+
+// Edit styles
+const (
+	ES_LEFT        = 0x0000
+	ES_CENTER      = 0x0001
+	ES_RIGHT       = 0x0002
+	ES_MULTILINE   = 0x0004
+	ES_UPPERCASE   = 0x0008
+	ES_LOWERCASE   = 0x0010
+	ES_PASSWORD    = 0x0020
+	ES_AUTOVSCROLL = 0x0040
+	ES_AUTOHSCROLL = 0x0080
+	ES_NOHIDESEL   = 0x0100
+	ES_OEMCONVERT  = 0x0400
+	ES_READONLY    = 0x0800
+	ES_WANTRETURN  = 0x1000
+	ES_NUMBER      = 0x2000
+)
+
+// Edit notifications
+const (
+	EN_SETFOCUS     = 0x0100
+	EN_KILLFOCUS    = 0x0200
+	EN_CHANGE       = 0x0300
+	EN_UPDATE       = 0x0400
+	EN_ERRSPACE     = 0x0500
+	EN_MAXTEXT      = 0x0501
+	EN_HSCROLL      = 0x0601
+	EN_VSCROLL      = 0x0602
+	EN_ALIGN_LTR_EC = 0x0700
+	EN_ALIGN_RTL_EC = 0x0701
+)
+
+// Edit messages
+const (
+	EM_GETSEL              = 0x00B0
+	EM_SETSEL              = 0x00B1
+	EM_GETRECT             = 0x00B2
+	EM_SETRECT             = 0x00B3
+	EM_SETRECTNP           = 0x00B4
+	EM_SCROLL              = 0x00B5
+	EM_LINESCROLL          = 0x00B6
+	EM_SCROLLCARET         = 0x00B7
+	EM_GETMODIFY           = 0x00B8
+	EM_SETMODIFY           = 0x00B9
+	EM_GETLINECOUNT        = 0x00BA
+	EM_LINEINDEX           = 0x00BB
+	EM_SETHANDLE           = 0x00BC
+	EM_GETHANDLE           = 0x00BD
+	EM_GETTHUMB            = 0x00BE
+	EM_LINELENGTH          = 0x00C1
+	EM_REPLACESEL          = 0x00C2
+	EM_GETLINE             = 0x00C4
+	EM_LIMITTEXT           = 0x00C5
+	EM_CANUNDO             = 0x00C6
+	EM_UNDO                = 0x00C7
+	EM_FMTLINES            = 0x00C8
+	EM_LINEFROMCHAR        = 0x00C9
+	EM_SETTABSTOPS         = 0x00CB
+	EM_SETPASSWORDCHAR     = 0x00CC
+	EM_EMPTYUNDOBUFFER     = 0x00CD
+	EM_GETFIRSTVISIBLELINE = 0x00CE
+	EM_SETREADONLY         = 0x00CF
+	EM_SETWORDBREAKPROC    = 0x00D0
+	EM_GETWORDBREAKPROC    = 0x00D1
+	EM_GETPASSWORDCHAR     = 0x00D2
+	EM_SETMARGINS          = 0x00D3
+	EM_GETMARGINS          = 0x00D4
+	EM_SETLIMITTEXT        = EM_LIMITTEXT
+	EM_GETLIMITTEXT        = 0x00D5
+	EM_POSFROMCHAR         = 0x00D6
+	EM_CHARFROMPOS         = 0x00D7
+	EM_SETIMESTATUS        = 0x00D8
+	EM_GETIMESTATUS        = 0x00D9
+	EM_SETCUEBANNER        = 0x1501
+	EM_GETCUEBANNER        = 0x1502
+)
+
+const (
+	CCM_FIRST            = 0x2000
+	CCM_LAST             = CCM_FIRST + 0x200
+	CCM_SETBKCOLOR       = 8193
+	CCM_SETCOLORSCHEME   = 8194
+	CCM_GETCOLORSCHEME   = 8195
+	CCM_GETDROPTARGET    = 8196
+	CCM_SETUNICODEFORMAT = 8197
+	CCM_GETUNICODEFORMAT = 8198
+	CCM_SETVERSION       = 0x2007
+	CCM_GETVERSION       = 0x2008
+	CCM_SETNOTIFYWINDOW  = 0x2009
+	CCM_SETWINDOWTHEME   = 0x200b
+	CCM_DPISCALE         = 0x200c
+)
+
+// Common controls styles
+const (
+	CCS_TOP           = 1
+	CCS_NOMOVEY       = 2
+	CCS_BOTTOM        = 3
+	CCS_NORESIZE      = 4
+	CCS_NOPARENTALIGN = 8
+	CCS_ADJUSTABLE    = 32
+	CCS_NODIVIDER     = 64
+	CCS_VERT          = 128
+	CCS_LEFT          = 129
+	CCS_NOMOVEX       = 130
+	CCS_RIGHT         = 131
+)
+
+// ProgressBar messages
+const (
+	PROGRESS_CLASS  = "msctls_progress32"
+	PBM_SETPOS      = WM_USER + 2
+	PBM_DELTAPOS    = WM_USER + 3
+	PBM_SETSTEP     = WM_USER + 4
+	PBM_STEPIT      = WM_USER + 5
+	PBM_SETRANGE32  = 1030
+	PBM_GETRANGE    = 1031
+	PBM_GETPOS      = 1032
+	PBM_SETBARCOLOR = 1033
+	PBM_SETBKCOLOR  = CCM_SETBKCOLOR
+	PBS_SMOOTH      = 1
+	PBS_VERTICAL    = 4
+)
+
+// GetOpenFileName and GetSaveFileName extended flags
+const (
+	OFN_EX_NOPLACESBAR = 0x00000001
+)
+
+// GetOpenFileName and GetSaveFileName flags
+const (
+	OFN_ALLOWMULTISELECT     = 0x00000200
+	OFN_CREATEPROMPT         = 0x00002000
+	OFN_DONTADDTORECENT      = 0x02000000
+	OFN_ENABLEHOOK           = 0x00000020
+	OFN_ENABLEINCLUDENOTIFY  = 0x00400000
+	OFN_ENABLESIZING         = 0x00800000
+	OFN_ENABLETEMPLATE       = 0x00000040
+	OFN_ENABLETEMPLATEHANDLE = 0x00000080
+	OFN_EXPLORER             = 0x00080000
+	OFN_EXTENSIONDIFFERENT   = 0x00000400
+	OFN_FILEMUSTEXIST        = 0x00001000
+	OFN_FORCESHOWHIDDEN      = 0x10000000
+	OFN_HIDEREADONLY         = 0x00000004
+	OFN_LONGNAMES            = 0x00200000
+	OFN_NOCHANGEDIR          = 0x00000008
+	OFN_NODEREFERENCELINKS   = 0x00100000
+	OFN_NOLONGNAMES          = 0x00040000
+	OFN_NONETWORKBUTTON      = 0x00020000
+	OFN_NOREADONLYRETURN     = 0x00008000
+	OFN_NOTESTFILECREATE     = 0x00010000
+	OFN_NOVALIDATE           = 0x00000100
+	OFN_OVERWRITEPROMPT      = 0x00000002
+	OFN_PATHMUSTEXIST        = 0x00000800
+	OFN_READONLY             = 0x00000001
+	OFN_SHAREAWARE           = 0x00004000
+	OFN_SHOWHELP             = 0x00000010
+)
+
+//SHBrowseForFolder flags
+const (
+	BIF_RETURNONLYFSDIRS    = 0x00000001
+	BIF_DONTGOBELOWDOMAIN   = 0x00000002
+	BIF_STATUSTEXT          = 0x00000004
+	BIF_RETURNFSANCESTORS   = 0x00000008
+	BIF_EDITBOX             = 0x00000010
+	BIF_VALIDATE            = 0x00000020
+	BIF_NEWDIALOGSTYLE      = 0x00000040
+	BIF_BROWSEINCLUDEURLS   = 0x00000080
+	BIF_USENEWUI            = BIF_EDITBOX | BIF_NEWDIALOGSTYLE
+	BIF_UAHINT              = 0x00000100
+	BIF_NONEWFOLDERBUTTON   = 0x00000200
+	BIF_NOTRANSLATETARGETS  = 0x00000400
+	BIF_BROWSEFORCOMPUTER   = 0x00001000
+	BIF_BROWSEFORPRINTER    = 0x00002000
+	BIF_BROWSEINCLUDEFILES  = 0x00004000
+	BIF_SHAREABLE           = 0x00008000
+	BIF_BROWSEFILEJUNCTIONS = 0x00010000
+)
+
+//MessageBox flags
+const (
+	MB_OK                = 0x00000000
+	MB_OKCANCEL          = 0x00000001
+	MB_ABORTRETRYIGNORE  = 0x00000002
+	MB_YESNOCANCEL       = 0x00000003
+	MB_YESNO             = 0x00000004
+	MB_RETRYCANCEL       = 0x00000005
+	MB_CANCELTRYCONTINUE = 0x00000006
+	MB_ICONHAND          = 0x00000010
+	MB_ICONQUESTION      = 0x00000020
+	MB_ICONEXCLAMATION   = 0x00000030
+	MB_ICONASTERISK      = 0x00000040
+	MB_USERICON          = 0x00000080
+	MB_ICONWARNING       = MB_ICONEXCLAMATION
+	MB_ICONERROR         = MB_ICONHAND
+	MB_ICONINFORMATION   = MB_ICONASTERISK
+	MB_ICONSTOP          = MB_ICONHAND
+	MB_DEFBUTTON1        = 0x00000000
+	MB_DEFBUTTON2        = 0x00000100
+	MB_DEFBUTTON3        = 0x00000200
+	MB_DEFBUTTON4        = 0x00000300
+)
+
+//COM
+const (
+	E_INVALIDARG  = 0x80070057
+	E_OUTOFMEMORY = 0x8007000E
+	E_UNEXPECTED  = 0x8000FFFF
+)
+
+const (
+	S_OK               = 0
+	S_FALSE            = 0x0001
+	RPC_E_CHANGED_MODE = 0x80010106
+)
+
+// GetSystemMetrics constants
+const (
+	SM_CXSCREEN             = 0
+	SM_CYSCREEN             = 1
+	SM_CXVSCROLL            = 2
+	SM_CYHSCROLL            = 3
+	SM_CYCAPTION            = 4
+	SM_CXBORDER             = 5
+	SM_CYBORDER             = 6
+	SM_CXDLGFRAME           = 7
+	SM_CYDLGFRAME           = 8
+	SM_CYVTHUMB             = 9
+	SM_CXHTHUMB             = 10
+	SM_CXICON               = 11
+	SM_CYICON               = 12
+	SM_CXCURSOR             = 13
+	SM_CYCURSOR             = 14
+	SM_CYMENU               = 15
+	SM_CXFULLSCREEN         = 16
+	SM_CYFULLSCREEN         = 17
+	SM_CYKANJIWINDOW        = 18
+	SM_MOUSEPRESENT         = 19
+	SM_CYVSCROLL            = 20
+	SM_CXHSCROLL            = 21
+	SM_DEBUG                = 22
+	SM_SWAPBUTTON           = 23
+	SM_RESERVED1            = 24
+	SM_RESERVED2            = 25
+	SM_RESERVED3            = 26
+	SM_RESERVED4            = 27
+	SM_CXMIN                = 28
+	SM_CYMIN                = 29
+	SM_CXSIZE               = 30
+	SM_CYSIZE               = 31
+	SM_CXFRAME              = 32
+	SM_CYFRAME              = 33
+	SM_CXMINTRACK           = 34
+	SM_CYMINTRACK           = 35
+	SM_CXDOUBLECLK          = 36
+	SM_CYDOUBLECLK          = 37
+	SM_CXICONSPACING        = 38
+	SM_CYICONSPACING        = 39
+	SM_MENUDROPALIGNMENT    = 40
+	SM_PENWINDOWS           = 41
+	SM_DBCSENABLED          = 42
+	SM_CMOUSEBUTTONS        = 43
+	SM_CXFIXEDFRAME         = SM_CXDLGFRAME
+	SM_CYFIXEDFRAME         = SM_CYDLGFRAME
+	SM_CXSIZEFRAME          = SM_CXFRAME
+	SM_CYSIZEFRAME          = SM_CYFRAME
+	SM_SECURE               = 44
+	SM_CXEDGE               = 45
+	SM_CYEDGE               = 46
+	SM_CXMINSPACING         = 47
+	SM_CYMINSPACING         = 48
+	SM_CXSMICON             = 49
+	SM_CYSMICON             = 50
+	SM_CYSMCAPTION          = 51
+	SM_CXSMSIZE             = 52
+	SM_CYSMSIZE             = 53
+	SM_CXMENUSIZE           = 54
+	SM_CYMENUSIZE           = 55
+	SM_ARRANGE              = 56
+	SM_CXMINIMIZED          = 57
+	SM_CYMINIMIZED          = 58
+	SM_CXMAXTRACK           = 59
+	SM_CYMAXTRACK           = 60
+	SM_CXMAXIMIZED          = 61
+	SM_CYMAXIMIZED          = 62
+	SM_NETWORK              = 63
+	SM_CLEANBOOT            = 67
+	SM_CXDRAG               = 68
+	SM_CYDRAG               = 69
+	SM_SHOWSOUNDS           = 70
+	SM_CXMENUCHECK          = 71
+	SM_CYMENUCHECK          = 72
+	SM_SLOWMACHINE          = 73
+	SM_MIDEASTENABLED       = 74
+	SM_MOUSEWHEELPRESENT    = 75
+	SM_XVIRTUALSCREEN       = 76
+	SM_YVIRTUALSCREEN       = 77
+	SM_CXVIRTUALSCREEN      = 78
+	SM_CYVIRTUALSCREEN      = 79
+	SM_CMONITORS            = 80
+	SM_SAMEDISPLAYFORMAT    = 81
+	SM_IMMENABLED           = 82
+	SM_CXFOCUSBORDER        = 83
+	SM_CYFOCUSBORDER        = 84
+	SM_TABLETPC             = 86
+	SM_MEDIACENTER          = 87
+	SM_STARTER              = 88
+	SM_SERVERR2             = 89
+	SM_CMETRICS             = 91
+	SM_REMOTESESSION        = 0x1000
+	SM_SHUTTINGDOWN         = 0x2000
+	SM_REMOTECONTROL        = 0x2001
+	SM_CARETBLINKINGENABLED = 0x2002
+)
+
+const (
+	CLSCTX_INPROC_SERVER   = 1
+	CLSCTX_INPROC_HANDLER  = 2
+	CLSCTX_LOCAL_SERVER    = 4
+	CLSCTX_INPROC_SERVER16 = 8
+	CLSCTX_REMOTE_SERVER   = 16
+	CLSCTX_ALL             = CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER
+	CLSCTX_INPROC          = CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER
+	CLSCTX_SERVER          = CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER
+)
+
+const (
+	COINIT_APARTMENTTHREADED = 0x2
+	COINIT_MULTITHREADED     = 0x0
+	COINIT_DISABLE_OLE1DDE   = 0x4
+	COINIT_SPEED_OVER_MEMORY = 0x8
+)
+
+const (
+	DISPATCH_METHOD         = 1
+	DISPATCH_PROPERTYGET    = 2
+	DISPATCH_PROPERTYPUT    = 4
+	DISPATCH_PROPERTYPUTREF = 8
+)
+
+const (
+	CC_FASTCALL = iota
+	CC_CDECL
+	CC_MSCPASCAL
+	CC_PASCAL = CC_MSCPASCAL
+	CC_MACPASCAL
+	CC_STDCALL
+	CC_FPFASTCALL
+	CC_SYSCALL
+	CC_MPWCDECL
+	CC_MPWPASCAL
+	CC_MAX = CC_MPWPASCAL
+)
+
+const (
+	VT_EMPTY           = 0x0
+	VT_NULL            = 0x1
+	VT_I2              = 0x2
+	VT_I4              = 0x3
+	VT_R4              = 0x4
+	VT_R8              = 0x5
+	VT_CY              = 0x6
+	VT_DATE            = 0x7
+	VT_BSTR            = 0x8
+	VT_DISPATCH        = 0x9
+	VT_ERROR           = 0xa
+	VT_BOOL            = 0xb
+	VT_VARIANT         = 0xc
+	VT_UNKNOWN         = 0xd
+	VT_DECIMAL         = 0xe
+	VT_I1              = 0x10
+	VT_UI1             = 0x11
+	VT_UI2             = 0x12
+	VT_UI4             = 0x13
+	VT_I8              = 0x14
+	VT_UI8             = 0x15
+	VT_INT             = 0x16
+	VT_UINT            = 0x17
+	VT_VOID            = 0x18
+	VT_HRESULT         = 0x19
+	VT_PTR             = 0x1a
+	VT_SAFEARRAY       = 0x1b
+	VT_CARRAY          = 0x1c
+	VT_USERDEFINED     = 0x1d
+	VT_LPSTR           = 0x1e
+	VT_LPWSTR          = 0x1f
+	VT_RECORD          = 0x24
+	VT_INT_PTR         = 0x25
+	VT_UINT_PTR        = 0x26
+	VT_FILETIME        = 0x40
+	VT_BLOB            = 0x41
+	VT_STREAM          = 0x42
+	VT_STORAGE         = 0x43
+	VT_STREAMED_OBJECT = 0x44
+	VT_STORED_OBJECT   = 0x45
+	VT_BLOB_OBJECT     = 0x46
+	VT_CF              = 0x47
+	VT_CLSID           = 0x48
+	VT_BSTR_BLOB       = 0xfff
+	VT_VECTOR          = 0x1000
+	VT_ARRAY           = 0x2000
+	VT_BYREF           = 0x4000
+	VT_RESERVED        = 0x8000
+	VT_ILLEGAL         = 0xffff
+	VT_ILLEGALMASKED   = 0xfff
+	VT_TYPEMASK        = 0xfff
+)
+
+const (
+	DISPID_UNKNOWN     = -1
+	DISPID_VALUE       = 0
+	DISPID_PROPERTYPUT = -3
+	DISPID_NEWENUM     = -4
+	DISPID_EVALUATE    = -5
+	DISPID_CONSTRUCTOR = -6
+	DISPID_DESTRUCTOR  = -7
+	DISPID_COLLECT     = -8
+)
+
+const (
+	MONITOR_DEFAULTTONULL    = 0x00000000
+	MONITOR_DEFAULTTOPRIMARY = 0x00000001
+	MONITOR_DEFAULTTONEAREST = 0x00000002
+
+	MONITORINFOF_PRIMARY = 0x00000001
+)
+
+const (
+	CCHDEVICENAME = 32
+	CCHFORMNAME   = 32
+)
+
+const (
+	IDOK       = 1
+	IDCANCEL   = 2
+	IDABORT    = 3
+	IDRETRY    = 4
+	IDIGNORE   = 5
+	IDYES      = 6
+	IDNO       = 7
+	IDCLOSE    = 8
+	IDHELP     = 9
+	IDTRYAGAIN = 10
+	IDCONTINUE = 11
+	IDTIMEOUT  = 32000
+)
+
+// Generic WM_NOTIFY notification codes
+const (
+	NM_FIRST           = 0
+	NM_OUTOFMEMORY     = NM_FIRST - 1
+	NM_CLICK           = NM_FIRST - 2
+	NM_DBLCLK          = NM_FIRST - 3
+	NM_RETURN          = NM_FIRST - 4
+	NM_RCLICK          = NM_FIRST - 5
+	NM_RDBLCLK         = NM_FIRST - 6
+	NM_SETFOCUS        = NM_FIRST - 7
+	NM_KILLFOCUS       = NM_FIRST - 8
+	NM_CUSTOMDRAW      = NM_FIRST - 12
+	NM_HOVER           = NM_FIRST - 13
+	NM_NCHITTEST       = NM_FIRST - 14
+	NM_KEYDOWN         = NM_FIRST - 15
+	NM_RELEASEDCAPTURE = NM_FIRST - 16
+	NM_SETCURSOR       = NM_FIRST - 17
+	NM_CHAR            = NM_FIRST - 18
+	NM_TOOLTIPSCREATED = NM_FIRST - 19
+	NM_LAST            = NM_FIRST - 99
+)
+
+// ListView messages
+const (
+	LVM_FIRST                    = 0x1000
+	LVM_GETITEMCOUNT             = LVM_FIRST + 4
+	LVM_SETIMAGELIST             = LVM_FIRST + 3
+	LVM_GETIMAGELIST             = LVM_FIRST + 2
+	LVM_GETITEM                  = LVM_FIRST + 75
+	LVM_SETITEM                  = LVM_FIRST + 76
+	LVM_INSERTITEM               = LVM_FIRST + 77
+	LVM_DELETEITEM               = LVM_FIRST + 8
+	LVM_DELETEALLITEMS           = LVM_FIRST + 9
+	LVM_GETCALLBACKMASK          = LVM_FIRST + 10
+	LVM_SETCALLBACKMASK          = LVM_FIRST + 11
+	LVM_SETUNICODEFORMAT         = CCM_SETUNICODEFORMAT
+	LVM_GETNEXTITEM              = LVM_FIRST + 12
+	LVM_FINDITEM                 = LVM_FIRST + 83
+	LVM_GETITEMRECT              = LVM_FIRST + 14
+	LVM_GETSTRINGWIDTH           = LVM_FIRST + 87
+	LVM_HITTEST                  = LVM_FIRST + 18
+	LVM_ENSUREVISIBLE            = LVM_FIRST + 19
+	LVM_SCROLL                   = LVM_FIRST + 20
+	LVM_REDRAWITEMS              = LVM_FIRST + 21
+	LVM_ARRANGE                  = LVM_FIRST + 22
+	LVM_EDITLABEL                = LVM_FIRST + 118
+	LVM_GETEDITCONTROL           = LVM_FIRST + 24
+	LVM_GETCOLUMN                = LVM_FIRST + 95
+	LVM_SETCOLUMN                = LVM_FIRST + 96
+	LVM_INSERTCOLUMN             = LVM_FIRST + 97
+	LVM_DELETECOLUMN             = LVM_FIRST + 28
+	LVM_GETCOLUMNWIDTH           = LVM_FIRST + 29
+	LVM_SETCOLUMNWIDTH           = LVM_FIRST + 30
+	LVM_GETHEADER                = LVM_FIRST + 31
+	LVM_CREATEDRAGIMAGE          = LVM_FIRST + 33
+	LVM_GETVIEWRECT              = LVM_FIRST + 34
+	LVM_GETTEXTCOLOR             = LVM_FIRST + 35
+	LVM_SETTEXTCOLOR             = LVM_FIRST + 36
+	LVM_GETTEXTBKCOLOR           = LVM_FIRST + 37
+	LVM_SETTEXTBKCOLOR           = LVM_FIRST + 38
+	LVM_GETTOPINDEX              = LVM_FIRST + 39
+	LVM_GETCOUNTPERPAGE          = LVM_FIRST + 40
+	LVM_GETORIGIN                = LVM_FIRST + 41
+	LVM_UPDATE                   = LVM_FIRST + 42
+	LVM_SETITEMSTATE             = LVM_FIRST + 43
+	LVM_GETITEMSTATE             = LVM_FIRST + 44
+	LVM_GETITEMTEXT              = LVM_FIRST + 115
+	LVM_SETITEMTEXT              = LVM_FIRST + 116
+	LVM_SETITEMCOUNT             = LVM_FIRST + 47
+	LVM_SORTITEMS                = LVM_FIRST + 48
+	LVM_SETITEMPOSITION32        = LVM_FIRST + 49
+	LVM_GETSELECTEDCOUNT         = LVM_FIRST + 50
+	LVM_GETITEMSPACING           = LVM_FIRST + 51
+	LVM_GETISEARCHSTRING         = LVM_FIRST + 117
+	LVM_SETICONSPACING           = LVM_FIRST + 53
+	LVM_SETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 54
+	LVM_GETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 55
+	LVM_GETSUBITEMRECT           = LVM_FIRST + 56
+	LVM_SUBITEMHITTEST           = LVM_FIRST + 57
+	LVM_SETCOLUMNORDERARRAY      = LVM_FIRST + 58
+	LVM_GETCOLUMNORDERARRAY      = LVM_FIRST + 59
+	LVM_SETHOTITEM               = LVM_FIRST + 60
+	LVM_GETHOTITEM               = LVM_FIRST + 61
+	LVM_SETHOTCURSOR             = LVM_FIRST + 62
+	LVM_GETHOTCURSOR             = LVM_FIRST + 63
+	LVM_APPROXIMATEVIEWRECT      = LVM_FIRST + 64
+	LVM_SETWORKAREAS             = LVM_FIRST + 65
+	LVM_GETWORKAREAS             = LVM_FIRST + 70
+	LVM_GETNUMBEROFWORKAREAS     = LVM_FIRST + 73
+	LVM_GETSELECTIONMARK         = LVM_FIRST + 66
+	LVM_SETSELECTIONMARK         = LVM_FIRST + 67
+	LVM_SETHOVERTIME             = LVM_FIRST + 71
+	LVM_GETHOVERTIME             = LVM_FIRST + 72
+	LVM_SETTOOLTIPS              = LVM_FIRST + 74
+	LVM_GETTOOLTIPS              = LVM_FIRST + 78
+	LVM_SORTITEMSEX              = LVM_FIRST + 81
+	LVM_SETBKIMAGE               = LVM_FIRST + 138
+	LVM_GETBKIMAGE               = LVM_FIRST + 139
+	LVM_SETSELECTEDCOLUMN        = LVM_FIRST + 140
+	LVM_SETVIEW                  = LVM_FIRST + 142
+	LVM_GETVIEW                  = LVM_FIRST + 143
+	LVM_INSERTGROUP              = LVM_FIRST + 145
+	LVM_SETGROUPINFO             = LVM_FIRST + 147
+	LVM_GETGROUPINFO             = LVM_FIRST + 149
+	LVM_REMOVEGROUP              = LVM_FIRST + 150
+	LVM_MOVEGROUP                = LVM_FIRST + 151
+	LVM_GETGROUPCOUNT            = LVM_FIRST + 152
+	LVM_GETGROUPINFOBYINDEX      = LVM_FIRST + 153
+	LVM_MOVEITEMTOGROUP          = LVM_FIRST + 154
+	LVM_GETGROUPRECT             = LVM_FIRST + 98
+	LVM_SETGROUPMETRICS          = LVM_FIRST + 155
+	LVM_GETGROUPMETRICS          = LVM_FIRST + 156
+	LVM_ENABLEGROUPVIEW          = LVM_FIRST + 157
+	LVM_SORTGROUPS               = LVM_FIRST + 158
+	LVM_INSERTGROUPSORTED        = LVM_FIRST + 159
+	LVM_REMOVEALLGROUPS          = LVM_FIRST + 160
+	LVM_HASGROUP                 = LVM_FIRST + 161
+	LVM_GETGROUPSTATE            = LVM_FIRST + 92
+	LVM_GETFOCUSEDGROUP          = LVM_FIRST + 93
+	LVM_SETTILEVIEWINFO          = LVM_FIRST + 162
+	LVM_GETTILEVIEWINFO          = LVM_FIRST + 163
+	LVM_SETTILEINFO              = LVM_FIRST + 164
+	LVM_GETTILEINFO              = LVM_FIRST + 165
+	LVM_SETINSERTMARK            = LVM_FIRST + 166
+	LVM_GETINSERTMARK            = LVM_FIRST + 167
+	LVM_INSERTMARKHITTEST        = LVM_FIRST + 168
+	LVM_GETINSERTMARKRECT        = LVM_FIRST + 169
+	LVM_SETINSERTMARKCOLOR       = LVM_FIRST + 170
+	LVM_GETINSERTMARKCOLOR       = LVM_FIRST + 171
+	LVM_SETINFOTIP               = LVM_FIRST + 173
+	LVM_GETSELECTEDCOLUMN        = LVM_FIRST + 174
+	LVM_ISGROUPVIEWENABLED       = LVM_FIRST + 175
+	LVM_GETOUTLINECOLOR          = LVM_FIRST + 176
+	LVM_SETOUTLINECOLOR          = LVM_FIRST + 177
+	LVM_CANCELEDITLABEL          = LVM_FIRST + 179
+	LVM_MAPINDEXTOID             = LVM_FIRST + 180
+	LVM_MAPIDTOINDEX             = LVM_FIRST + 181
+	LVM_ISITEMVISIBLE            = LVM_FIRST + 182
+	LVM_GETNEXTITEMINDEX         = LVM_FIRST + 211
+)
+
+// ListView notifications
+const (
+	LVN_FIRST = -100
+
+	LVN_ITEMCHANGING      = LVN_FIRST - 0
+	LVN_ITEMCHANGED       = LVN_FIRST - 1
+	LVN_INSERTITEM        = LVN_FIRST - 2
+	LVN_DELETEITEM        = LVN_FIRST - 3
+	LVN_DELETEALLITEMS    = LVN_FIRST - 4
+	LVN_BEGINLABELEDITA   = LVN_FIRST - 5
+	LVN_BEGINLABELEDITW   = LVN_FIRST - 75
+	LVN_ENDLABELEDITA     = LVN_FIRST - 6
+	LVN_ENDLABELEDITW     = LVN_FIRST - 76
+	LVN_COLUMNCLICK       = LVN_FIRST - 8
+	LVN_BEGINDRAG         = LVN_FIRST - 9
+	LVN_BEGINRDRAG        = LVN_FIRST - 11
+	LVN_ODCACHEHINT       = LVN_FIRST - 13
+	LVN_ODFINDITEMA       = LVN_FIRST - 52
+	LVN_ODFINDITEMW       = LVN_FIRST - 79
+	LVN_ITEMACTIVATE      = LVN_FIRST - 14
+	LVN_ODSTATECHANGED    = LVN_FIRST - 15
+	LVN_HOTTRACK          = LVN_FIRST - 21
+	LVN_GETDISPINFO       = LVN_FIRST - 77
+	LVN_SETDISPINFO       = LVN_FIRST - 78
+	LVN_KEYDOWN           = LVN_FIRST - 55
+	LVN_MARQUEEBEGIN      = LVN_FIRST - 56
+	LVN_GETINFOTIP        = LVN_FIRST - 58
+	LVN_INCREMENTALSEARCH = LVN_FIRST - 63
+	LVN_BEGINSCROLL       = LVN_FIRST - 80
+	LVN_ENDSCROLL         = LVN_FIRST - 81
+)
+
+// ListView LVNI constants
+const (
+	LVNI_ALL         = 0
+	LVNI_FOCUSED     = 1
+	LVNI_SELECTED    = 2
+	LVNI_CUT         = 4
+	LVNI_DROPHILITED = 8
+	LVNI_ABOVE       = 256
+	LVNI_BELOW       = 512
+	LVNI_TOLEFT      = 1024
+	LVNI_TORIGHT     = 2048
+)
+
+// ListView styles
+const (
+	LVS_ICON            = 0x0000
+	LVS_REPORT          = 0x0001
+	LVS_SMALLICON       = 0x0002
+	LVS_LIST            = 0x0003
+	LVS_TYPEMASK        = 0x0003
+	LVS_SINGLESEL       = 0x0004
+	LVS_SHOWSELALWAYS   = 0x0008
+	LVS_SORTASCENDING   = 0x0010
+	LVS_SORTDESCENDING  = 0x0020
+	LVS_SHAREIMAGELISTS = 0x0040
+	LVS_NOLABELWRAP     = 0x0080
+	LVS_AUTOARRANGE     = 0x0100
+	LVS_EDITLABELS      = 0x0200
+	LVS_OWNERDATA       = 0x1000
+	LVS_NOSCROLL        = 0x2000
+	LVS_TYPESTYLEMASK   = 0xfc00
+	LVS_ALIGNTOP        = 0x0000
+	LVS_ALIGNLEFT       = 0x0800
+	LVS_ALIGNMASK       = 0x0c00
+	LVS_OWNERDRAWFIXED  = 0x0400
+	LVS_NOCOLUMNHEADER  = 0x4000
+	LVS_NOSORTHEADER    = 0x8000
+)
+
+// ListView extended styles
+const (
+	LVS_EX_GRIDLINES        = 0x00000001
+	LVS_EX_SUBITEMIMAGES    = 0x00000002
+	LVS_EX_CHECKBOXES       = 0x00000004
+	LVS_EX_TRACKSELECT      = 0x00000008
+	LVS_EX_HEADERDRAGDROP   = 0x00000010
+	LVS_EX_FULLROWSELECT    = 0x00000020
+	LVS_EX_ONECLICKACTIVATE = 0x00000040
+	LVS_EX_TWOCLICKACTIVATE = 0x00000080
+	LVS_EX_FLATSB           = 0x00000100
+	LVS_EX_REGIONAL         = 0x00000200
+	LVS_EX_INFOTIP          = 0x00000400
+	LVS_EX_UNDERLINEHOT     = 0x00000800
+	LVS_EX_UNDERLINECOLD    = 0x00001000
+	LVS_EX_MULTIWORKAREAS   = 0x00002000
+	LVS_EX_LABELTIP         = 0x00004000
+	LVS_EX_BORDERSELECT     = 0x00008000
+	LVS_EX_DOUBLEBUFFER     = 0x00010000
+	LVS_EX_HIDELABELS       = 0x00020000
+	LVS_EX_SINGLEROW        = 0x00040000
+	LVS_EX_SNAPTOGRID       = 0x00080000
+	LVS_EX_SIMPLESELECT     = 0x00100000
+)
+
+// ListView column flags
+const (
+	LVCF_FMT     = 0x0001
+	LVCF_WIDTH   = 0x0002
+	LVCF_TEXT    = 0x0004
+	LVCF_SUBITEM = 0x0008
+	LVCF_IMAGE   = 0x0010
+	LVCF_ORDER   = 0x0020
+)
+
+// ListView column format constants
+const (
+	LVCFMT_LEFT            = 0x0000
+	LVCFMT_RIGHT           = 0x0001
+	LVCFMT_CENTER          = 0x0002
+	LVCFMT_JUSTIFYMASK     = 0x0003
+	LVCFMT_IMAGE           = 0x0800
+	LVCFMT_BITMAP_ON_RIGHT = 0x1000
+	LVCFMT_COL_HAS_IMAGES  = 0x8000
+)
+
+// ListView item flags
+const (
+	LVIF_TEXT        = 0x00000001
+	LVIF_IMAGE       = 0x00000002
+	LVIF_PARAM       = 0x00000004
+	LVIF_STATE       = 0x00000008
+	LVIF_INDENT      = 0x00000010
+	LVIF_NORECOMPUTE = 0x00000800
+	LVIF_GROUPID     = 0x00000100
+	LVIF_COLUMNS     = 0x00000200
+)
+
+// ListView item states
+const (
+	LVIS_FOCUSED        = 1
+	LVIS_SELECTED       = 2
+	LVIS_CUT            = 4
+	LVIS_DROPHILITED    = 8
+	LVIS_OVERLAYMASK    = 0xF00
+	LVIS_STATEIMAGEMASK = 0xF000
+)
+
+// ListView hit test constants
+const (
+	LVHT_NOWHERE         = 0x00000001
+	LVHT_ONITEMICON      = 0x00000002
+	LVHT_ONITEMLABEL     = 0x00000004
+	LVHT_ONITEMSTATEICON = 0x00000008
+	LVHT_ONITEM          = LVHT_ONITEMICON | LVHT_ONITEMLABEL | LVHT_ONITEMSTATEICON
+
+	LVHT_ABOVE   = 0x00000008
+	LVHT_BELOW   = 0x00000010
+	LVHT_TORIGHT = 0x00000020
+	LVHT_TOLEFT  = 0x00000040
+)
+
+// ListView image list types
+const (
+	LVSIL_NORMAL      = 0
+	LVSIL_SMALL       = 1
+	LVSIL_STATE       = 2
+	LVSIL_GROUPHEADER = 3
+)
+
+// InitCommonControlsEx flags
+const (
+	ICC_LISTVIEW_CLASSES   = 1
+	ICC_TREEVIEW_CLASSES   = 2
+	ICC_BAR_CLASSES        = 4
+	ICC_TAB_CLASSES        = 8
+	ICC_UPDOWN_CLASS       = 16
+	ICC_PROGRESS_CLASS     = 32
+	ICC_HOTKEY_CLASS       = 64
+	ICC_ANIMATE_CLASS      = 128
+	ICC_WIN95_CLASSES      = 255
+	ICC_DATE_CLASSES       = 256
+	ICC_USEREX_CLASSES     = 512
+	ICC_COOL_CLASSES       = 1024
+	ICC_INTERNET_CLASSES   = 2048
+	ICC_PAGESCROLLER_CLASS = 4096
+	ICC_NATIVEFNTCTL_CLASS = 8192
+	INFOTIPSIZE            = 1024
+	ICC_STANDARD_CLASSES   = 0x00004000
+	ICC_LINK_CLASS         = 0x00008000
+)
+
+// Dialog Codes
+const (
+	DLGC_WANTARROWS      = 0x0001
+	DLGC_WANTTAB         = 0x0002
+	DLGC_WANTALLKEYS     = 0x0004
+	DLGC_WANTMESSAGE     = 0x0004
+	DLGC_HASSETSEL       = 0x0008
+	DLGC_DEFPUSHBUTTON   = 0x0010
+	DLGC_UNDEFPUSHBUTTON = 0x0020
+	DLGC_RADIOBUTTON     = 0x0040
+	DLGC_WANTCHARS       = 0x0080
+	DLGC_STATIC          = 0x0100
+	DLGC_BUTTON          = 0x2000
+)
+
+// Get/SetWindowWord/Long offsets for use with WC_DIALOG windows
+const (
+	DWL_MSGRESULT = 0
+	DWL_DLGPROC   = 4
+	DWL_USER      = 8
+)
+
+// PeekMessage wRemoveMsg value
+const (
+	PM_NOREMOVE = 0x000
+	PM_REMOVE   = 0x001
+	PM_NOYIELD  = 0x002
+)
+
+// ImageList flags
+const (
+	ILC_MASK             = 0x00000001
+	ILC_COLOR            = 0x00000000
+	ILC_COLORDDB         = 0x000000FE
+	ILC_COLOR4           = 0x00000004
+	ILC_COLOR8           = 0x00000008
+	ILC_COLOR16          = 0x00000010
+	ILC_COLOR24          = 0x00000018
+	ILC_COLOR32          = 0x00000020
+	ILC_PALETTE          = 0x00000800
+	ILC_MIRROR           = 0x00002000
+	ILC_PERITEMMIRROR    = 0x00008000
+	ILC_ORIGINALSIZE     = 0x00010000
+	ILC_HIGHQUALITYSCALE = 0x00020000
+)
+
+// Keystroke Message Flags
+const (
+	KF_EXTENDED = 0x0100
+	KF_DLGMODE  = 0x0800
+	KF_MENUMODE = 0x1000
+	KF_ALTDOWN  = 0x2000
+	KF_REPEAT   = 0x4000
+	KF_UP       = 0x8000
+)
+
+// Virtual-Key Codes
+const (
+	VK_LBUTTON             = 0x01
+	VK_RBUTTON             = 0x02
+	VK_CANCEL              = 0x03
+	VK_MBUTTON             = 0x04
+	VK_XBUTTON1            = 0x05
+	VK_XBUTTON2            = 0x06
+	VK_BACK                = 0x08
+	VK_TAB                 = 0x09
+	VK_CLEAR               = 0x0C
+	VK_RETURN              = 0x0D
+	VK_SHIFT               = 0x10
+	VK_CONTROL             = 0x11
+	VK_MENU                = 0x12
+	VK_PAUSE               = 0x13
+	VK_CAPITAL             = 0x14
+	VK_KANA                = 0x15
+	VK_HANGEUL             = 0x15
+	VK_HANGUL              = 0x15
+	VK_JUNJA               = 0x17
+	VK_FINAL               = 0x18
+	VK_HANJA               = 0x19
+	VK_KANJI               = 0x19
+	VK_ESCAPE              = 0x1B
+	VK_CONVERT             = 0x1C
+	VK_NONCONVERT          = 0x1D
+	VK_ACCEPT              = 0x1E
+	VK_MODECHANGE          = 0x1F
+	VK_SPACE               = 0x20
+	VK_PRIOR               = 0x21
+	VK_NEXT                = 0x22
+	VK_END                 = 0x23
+	VK_HOME                = 0x24
+	VK_LEFT                = 0x25
+	VK_UP                  = 0x26
+	VK_RIGHT               = 0x27
+	VK_DOWN                = 0x28
+	VK_SELECT              = 0x29
+	VK_PRINT               = 0x2A
+	VK_EXECUTE             = 0x2B
+	VK_SNAPSHOT            = 0x2C
+	VK_INSERT              = 0x2D
+	VK_DELETE              = 0x2E
+	VK_HELP                = 0x2F
+	VK_LWIN                = 0x5B
+	VK_RWIN                = 0x5C
+	VK_APPS                = 0x5D
+	VK_SLEEP               = 0x5F
+	VK_NUMPAD0             = 0x60
+	VK_NUMPAD1             = 0x61
+	VK_NUMPAD2             = 0x62
+	VK_NUMPAD3             = 0x63
+	VK_NUMPAD4             = 0x64
+	VK_NUMPAD5             = 0x65
+	VK_NUMPAD6             = 0x66
+	VK_NUMPAD7             = 0x67
+	VK_NUMPAD8             = 0x68
+	VK_NUMPAD9             = 0x69
+	VK_MULTIPLY            = 0x6A
+	VK_ADD                 = 0x6B
+	VK_SEPARATOR           = 0x6C
+	VK_SUBTRACT            = 0x6D
+	VK_DECIMAL             = 0x6E
+	VK_DIVIDE              = 0x6F
+	VK_F1                  = 0x70
+	VK_F2                  = 0x71
+	VK_F3                  = 0x72
+	VK_F4                  = 0x73
+	VK_F5                  = 0x74
+	VK_F6                  = 0x75
+	VK_F7                  = 0x76
+	VK_F8                  = 0x77
+	VK_F9                  = 0x78
+	VK_F10                 = 0x79
+	VK_F11                 = 0x7A
+	VK_F12                 = 0x7B
+	VK_F13                 = 0x7C
+	VK_F14                 = 0x7D
+	VK_F15                 = 0x7E
+	VK_F16                 = 0x7F
+	VK_F17                 = 0x80
+	VK_F18                 = 0x81
+	VK_F19                 = 0x82
+	VK_F20                 = 0x83
+	VK_F21                 = 0x84
+	VK_F22                 = 0x85
+	VK_F23                 = 0x86
+	VK_F24                 = 0x87
+	VK_NUMLOCK             = 0x90
+	VK_SCROLL              = 0x91
+	VK_OEM_NEC_EQUAL       = 0x92
+	VK_OEM_FJ_JISHO        = 0x92
+	VK_OEM_FJ_MASSHOU      = 0x93
+	VK_OEM_FJ_TOUROKU      = 0x94
+	VK_OEM_FJ_LOYA         = 0x95
+	VK_OEM_FJ_ROYA         = 0x96
+	VK_LSHIFT              = 0xA0
+	VK_RSHIFT              = 0xA1
+	VK_LCONTROL            = 0xA2
+	VK_RCONTROL            = 0xA3
+	VK_LMENU               = 0xA4
+	VK_RMENU               = 0xA5
+	VK_BROWSER_BACK        = 0xA6
+	VK_BROWSER_FORWARD     = 0xA7
+	VK_BROWSER_REFRESH     = 0xA8
+	VK_BROWSER_STOP        = 0xA9
+	VK_BROWSER_SEARCH      = 0xAA
+	VK_BROWSER_FAVORITES   = 0xAB
+	VK_BROWSER_HOME        = 0xAC
+	VK_VOLUME_MUTE         = 0xAD
+	VK_VOLUME_DOWN         = 0xAE
+	VK_VOLUME_UP           = 0xAF
+	VK_MEDIA_NEXT_TRACK    = 0xB0
+	VK_MEDIA_PREV_TRACK    = 0xB1
+	VK_MEDIA_STOP          = 0xB2
+	VK_MEDIA_PLAY_PAUSE    = 0xB3
+	VK_LAUNCH_MAIL         = 0xB4
+	VK_LAUNCH_MEDIA_SELECT = 0xB5
+	VK_LAUNCH_APP1         = 0xB6
+	VK_LAUNCH_APP2         = 0xB7
+	VK_OEM_1               = 0xBA
+	VK_OEM_PLUS            = 0xBB
+	VK_OEM_COMMA           = 0xBC
+	VK_OEM_MINUS           = 0xBD
+	VK_OEM_PERIOD          = 0xBE
+	VK_OEM_2               = 0xBF
+	VK_OEM_3               = 0xC0
+	VK_OEM_4               = 0xDB
+	VK_OEM_5               = 0xDC
+	VK_OEM_6               = 0xDD
+	VK_OEM_7               = 0xDE
+	VK_OEM_8               = 0xDF
+	VK_OEM_AX              = 0xE1
+	VK_OEM_102             = 0xE2
+	VK_ICO_HELP            = 0xE3
+	VK_ICO_00              = 0xE4
+	VK_PROCESSKEY          = 0xE5
+	VK_ICO_CLEAR           = 0xE6
+	VK_PACKET              = 0xE7
+	VK_OEM_RESET           = 0xE9
+	VK_OEM_JUMP            = 0xEA
+	VK_OEM_PA1             = 0xEB
+	VK_OEM_PA2             = 0xEC
+	VK_OEM_PA3             = 0xED
+	VK_OEM_WSCTRL          = 0xEE
+	VK_OEM_CUSEL           = 0xEF
+	VK_OEM_ATTN            = 0xF0
+	VK_OEM_FINISH          = 0xF1
+	VK_OEM_COPY            = 0xF2
+	VK_OEM_AUTO            = 0xF3
+	VK_OEM_ENLW            = 0xF4
+	VK_OEM_BACKTAB         = 0xF5
+	VK_ATTN                = 0xF6
+	VK_CRSEL               = 0xF7
+	VK_EXSEL               = 0xF8
+	VK_EREOF               = 0xF9
+	VK_PLAY                = 0xFA
+	VK_ZOOM                = 0xFB
+	VK_NONAME              = 0xFC
+	VK_PA1                 = 0xFD
+	VK_OEM_CLEAR           = 0xFE
+)
+
+// Registry Value Types
+const (
+	REG_NONE                       = 0
+	REG_SZ                         = 1
+	REG_EXPAND_SZ                  = 2
+	REG_BINARY                     = 3
+	REG_DWORD                      = 4
+	REG_DWORD_LITTLE_ENDIAN        = 4
+	REG_DWORD_BIG_ENDIAN           = 5
+	REG_LINK                       = 6
+	REG_MULTI_SZ                   = 7
+	REG_RESOURCE_LIST              = 8
+	REG_FULL_RESOURCE_DESCRIPTOR   = 9
+	REG_RESOURCE_REQUIREMENTS_LIST = 10
+	REG_QWORD                      = 11
+	REG_QWORD_LITTLE_ENDIAN        = 11
+)
+
+// Tooltip styles
+const (
+	TTS_ALWAYSTIP      = 0x01
+	TTS_NOPREFIX       = 0x02
+	TTS_NOANIMATE      = 0x10
+	TTS_NOFADE         = 0x20
+	TTS_BALLOON        = 0x40
+	TTS_CLOSE          = 0x80
+	TTS_USEVISUALSTYLE = 0x100
+)
+
+// Tooltip messages
+const (
+	TTM_ACTIVATE        = (WM_USER + 1)
+	TTM_SETDELAYTIME    = (WM_USER + 3)
+	TTM_ADDTOOL         = (WM_USER + 50)
+	TTM_DELTOOL         = (WM_USER + 51)
+	TTM_NEWTOOLRECT     = (WM_USER + 52)
+	TTM_RELAYEVENT      = (WM_USER + 7)
+	TTM_GETTOOLINFO     = (WM_USER + 53)
+	TTM_SETTOOLINFO     = (WM_USER + 54)
+	TTM_HITTEST         = (WM_USER + 55)
+	TTM_GETTEXT         = (WM_USER + 56)
+	TTM_UPDATETIPTEXT   = (WM_USER + 57)
+	TTM_GETTOOLCOUNT    = (WM_USER + 13)
+	TTM_ENUMTOOLS       = (WM_USER + 58)
+	TTM_GETCURRENTTOOL  = (WM_USER + 59)
+	TTM_WINDOWFROMPOINT = (WM_USER + 16)
+	TTM_TRACKACTIVATE   = (WM_USER + 17)
+	TTM_TRACKPOSITION   = (WM_USER + 18)
+	TTM_SETTIPBKCOLOR   = (WM_USER + 19)
+	TTM_SETTIPTEXTCOLOR = (WM_USER + 20)
+	TTM_GETDELAYTIME    = (WM_USER + 21)
+	TTM_GETTIPBKCOLOR   = (WM_USER + 22)
+	TTM_GETTIPTEXTCOLOR = (WM_USER + 23)
+	TTM_SETMAXTIPWIDTH  = (WM_USER + 24)
+	TTM_GETMAXTIPWIDTH  = (WM_USER + 25)
+	TTM_SETMARGIN       = (WM_USER + 26)
+	TTM_GETMARGIN       = (WM_USER + 27)
+	TTM_POP             = (WM_USER + 28)
+	TTM_UPDATE          = (WM_USER + 29)
+	TTM_GETBUBBLESIZE   = (WM_USER + 30)
+	TTM_ADJUSTRECT      = (WM_USER + 31)
+	TTM_SETTITLE        = (WM_USER + 33)
+	TTM_POPUP           = (WM_USER + 34)
+	TTM_GETTITLE        = (WM_USER + 35)
+)
+
+// Tooltip icons
+const (
+	TTI_NONE          = 0
+	TTI_INFO          = 1
+	TTI_WARNING       = 2
+	TTI_ERROR         = 3
+	TTI_INFO_LARGE    = 4
+	TTI_WARNING_LARGE = 5
+	TTI_ERROR_LARGE   = 6
+)
+
+// Tooltip notifications
+const (
+	TTN_FIRST       = -520
+	TTN_LAST        = -549
+	TTN_GETDISPINFO = (TTN_FIRST - 10)
+	TTN_SHOW        = (TTN_FIRST - 1)
+	TTN_POP         = (TTN_FIRST - 2)
+	TTN_LINKCLICK   = (TTN_FIRST - 3)
+	TTN_NEEDTEXT    = TTN_GETDISPINFO
+)
+
+const (
+	TTF_IDISHWND    = 0x0001
+	TTF_CENTERTIP   = 0x0002
+	TTF_RTLREADING  = 0x0004
+	TTF_SUBCLASS    = 0x0010
+	TTF_TRACK       = 0x0020
+	TTF_ABSOLUTE    = 0x0080
+	TTF_TRANSPARENT = 0x0100
+	TTF_PARSELINKS  = 0x1000
+	TTF_DI_SETITEM  = 0x8000
+)
+
+const (
+	SWP_NOSIZE         = 0x0001
+	SWP_NOMOVE         = 0x0002
+	SWP_NOZORDER       = 0x0004
+	SWP_NOREDRAW       = 0x0008
+	SWP_NOACTIVATE     = 0x0010
+	SWP_FRAMECHANGED   = 0x0020
+	SWP_SHOWWINDOW     = 0x0040
+	SWP_HIDEWINDOW     = 0x0080
+	SWP_NOCOPYBITS     = 0x0100
+	SWP_NOOWNERZORDER  = 0x0200
+	SWP_NOSENDCHANGING = 0x0400
+	SWP_DRAWFRAME      = SWP_FRAMECHANGED
+	SWP_NOREPOSITION   = SWP_NOOWNERZORDER
+	SWP_DEFERERASE     = 0x2000
+	SWP_ASYNCWINDOWPOS = 0x4000
+)
+
+// Predefined window handles
+const (
+	HWND_BROADCAST = HWND(0xFFFF)
+	HWND_BOTTOM    = HWND(1)
+	HWND_NOTOPMOST = ^HWND(1) // -2
+	HWND_TOP       = HWND(0)
+	HWND_TOPMOST   = ^HWND(0) // -1
+	HWND_DESKTOP   = HWND(0)
+	HWND_MESSAGE   = ^HWND(2) // -3
+)
+
+// Pen types
+const (
+	PS_COSMETIC  = 0x00000000
+	PS_GEOMETRIC = 0x00010000
+	PS_TYPE_MASK = 0x000F0000
+)
+
+// Pen styles
+const (
+	PS_SOLID       = 0
+	PS_DASH        = 1
+	PS_DOT         = 2
+	PS_DASHDOT     = 3
+	PS_DASHDOTDOT  = 4
+	PS_NULL        = 5
+	PS_INSIDEFRAME = 6
+	PS_USERSTYLE   = 7
+	PS_ALTERNATE   = 8
+	PS_STYLE_MASK  = 0x0000000F
+)
+
+// Pen cap types
+const (
+	PS_ENDCAP_ROUND  = 0x00000000
+	PS_ENDCAP_SQUARE = 0x00000100
+	PS_ENDCAP_FLAT   = 0x00000200
+	PS_ENDCAP_MASK   = 0x00000F00
+)
+
+// Pen join types
+const (
+	PS_JOIN_ROUND = 0x00000000
+	PS_JOIN_BEVEL = 0x00001000
+	PS_JOIN_MITER = 0x00002000
+	PS_JOIN_MASK  = 0x0000F000
+)
+
+// Hatch styles
+const (
+	HS_HORIZONTAL = 0
+	HS_VERTICAL   = 1
+	HS_FDIAGONAL  = 2
+	HS_BDIAGONAL  = 3
+	HS_CROSS      = 4
+	HS_DIAGCROSS  = 5
+)
+
+// Stock Logical Objects
+const (
+	WHITE_BRUSH         = 0
+	LTGRAY_BRUSH        = 1
+	GRAY_BRUSH          = 2
+	DKGRAY_BRUSH        = 3
+	BLACK_BRUSH         = 4
+	NULL_BRUSH          = 5
+	HOLLOW_BRUSH        = NULL_BRUSH
+	WHITE_PEN           = 6
+	BLACK_PEN           = 7
+	NULL_PEN            = 8
+	OEM_FIXED_FONT      = 10
+	ANSI_FIXED_FONT     = 11
+	ANSI_VAR_FONT       = 12
+	SYSTEM_FONT         = 13
+	DEVICE_DEFAULT_FONT = 14
+	DEFAULT_PALETTE     = 15
+	SYSTEM_FIXED_FONT   = 16
+	DEFAULT_GUI_FONT    = 17
+	DC_BRUSH            = 18
+	DC_PEN              = 19
+)
+
+// Brush styles
+const (
+	BS_SOLID         = 0
+	BS_NULL          = 1
+	BS_HOLLOW        = BS_NULL
+	BS_HATCHED       = 2
+	BS_PATTERN       = 3
+	BS_INDEXED       = 4
+	BS_DIBPATTERN    = 5
+	BS_DIBPATTERNPT  = 6
+	BS_PATTERN8X8    = 7
+	BS_DIBPATTERN8X8 = 8
+	BS_MONOPATTERN   = 9
+)
+
+// TRACKMOUSEEVENT flags
+const (
+	TME_HOVER     = 0x00000001
+	TME_LEAVE     = 0x00000002
+	TME_NONCLIENT = 0x00000010
+	TME_QUERY     = 0x40000000
+	TME_CANCEL    = 0x80000000
+
+	HOVER_DEFAULT = 0xFFFFFFFF
+)
+
+// WM_NCHITTEST and MOUSEHOOKSTRUCT Mouse Position Codes
+const (
+	HTERROR       = (-2)
+	HTTRANSPARENT = (-1)
+	HTNOWHERE     = 0
+	HTCLIENT      = 1
+	HTCAPTION     = 2
+	HTSYSMENU     = 3
+	HTGROWBOX     = 4
+	HTSIZE        = HTGROWBOX
+	HTMENU        = 5
+	HTHSCROLL     = 6
+	HTVSCROLL     = 7
+	HTMINBUTTON   = 8
+	HTMAXBUTTON   = 9
+	HTLEFT        = 10
+	HTRIGHT       = 11
+	HTTOP         = 12
+	HTTOPLEFT     = 13
+	HTTOPRIGHT    = 14
+	HTBOTTOM      = 15
+	HTBOTTOMLEFT  = 16
+	HTBOTTOMRIGHT = 17
+	HTBORDER      = 18
+	HTREDUCE      = HTMINBUTTON
+	HTZOOM        = HTMAXBUTTON
+	HTSIZEFIRST   = HTLEFT
+	HTSIZELAST    = HTBOTTOMRIGHT
+	HTOBJECT      = 19
+	HTCLOSE       = 20
+	HTHELP        = 21
+)
+
+// DrawText[Ex] format flags
+const (
+	DT_TOP                  = 0x00000000
+	DT_LEFT                 = 0x00000000
+	DT_CENTER               = 0x00000001
+	DT_RIGHT                = 0x00000002
+	DT_VCENTER              = 0x00000004
+	DT_BOTTOM               = 0x00000008
+	DT_WORDBREAK            = 0x00000010
+	DT_SINGLELINE           = 0x00000020
+	DT_EXPANDTABS           = 0x00000040
+	DT_TABSTOP              = 0x00000080
+	DT_NOCLIP               = 0x00000100
+	DT_EXTERNALLEADING      = 0x00000200
+	DT_CALCRECT             = 0x00000400
+	DT_NOPREFIX             = 0x00000800
+	DT_INTERNAL             = 0x00001000
+	DT_EDITCONTROL          = 0x00002000
+	DT_PATH_ELLIPSIS        = 0x00004000
+	DT_END_ELLIPSIS         = 0x00008000
+	DT_MODIFYSTRING         = 0x00010000
+	DT_RTLREADING           = 0x00020000
+	DT_WORD_ELLIPSIS        = 0x00040000
+	DT_NOFULLWIDTHCHARBREAK = 0x00080000
+	DT_HIDEPREFIX           = 0x00100000
+	DT_PREFIXONLY           = 0x00200000
+)
+
+const CLR_INVALID = 0xFFFFFFFF
+
+// Background Modes
+const (
+	TRANSPARENT = 1
+	OPAQUE      = 2
+	BKMODE_LAST = 2
+)
+
+// Global Memory Flags
+const (
+	GMEM_FIXED          = 0x0000
+	GMEM_MOVEABLE       = 0x0002
+	GMEM_NOCOMPACT      = 0x0010
+	GMEM_NODISCARD      = 0x0020
+	GMEM_ZEROINIT       = 0x0040
+	GMEM_MODIFY         = 0x0080
+	GMEM_DISCARDABLE    = 0x0100
+	GMEM_NOT_BANKED     = 0x1000
+	GMEM_SHARE          = 0x2000
+	GMEM_DDESHARE       = 0x2000
+	GMEM_NOTIFY         = 0x4000
+	GMEM_LOWER          = GMEM_NOT_BANKED
+	GMEM_VALID_FLAGS    = 0x7F72
+	GMEM_INVALID_HANDLE = 0x8000
+	GHND                = (GMEM_MOVEABLE | GMEM_ZEROINIT)
+	GPTR                = (GMEM_FIXED | GMEM_ZEROINIT)
+)
+
+// Ternary raster operations
+const (
+	SRCCOPY        = 0x00CC0020
+	SRCPAINT       = 0x00EE0086
+	SRCAND         = 0x008800C6
+	SRCINVERT      = 0x00660046
+	SRCERASE       = 0x00440328
+	NOTSRCCOPY     = 0x00330008
+	NOTSRCERASE    = 0x001100A6
+	MERGECOPY      = 0x00C000CA
+	MERGEPAINT     = 0x00BB0226
+	PATCOPY        = 0x00F00021
+	PATPAINT       = 0x00FB0A09
+	PATINVERT      = 0x005A0049
+	DSTINVERT      = 0x00550009
+	BLACKNESS      = 0x00000042
+	WHITENESS      = 0x00FF0062
+	NOMIRRORBITMAP = 0x80000000
+	CAPTUREBLT     = 0x40000000
+)
+
+// Clipboard formats
+const (
+	CF_TEXT            = 1
+	CF_BITMAP          = 2
+	CF_METAFILEPICT    = 3
+	CF_SYLK            = 4
+	CF_DIF             = 5
+	CF_TIFF            = 6
+	CF_OEMTEXT         = 7
+	CF_DIB             = 8
+	CF_PALETTE         = 9
+	CF_PENDATA         = 10
+	CF_RIFF            = 11
+	CF_WAVE            = 12
+	CF_UNICODETEXT     = 13
+	CF_ENHMETAFILE     = 14
+	CF_HDROP           = 15
+	CF_LOCALE          = 16
+	CF_DIBV5           = 17
+	CF_MAX             = 18
+	CF_OWNERDISPLAY    = 0x0080
+	CF_DSPTEXT         = 0x0081
+	CF_DSPBITMAP       = 0x0082
+	CF_DSPMETAFILEPICT = 0x0083
+	CF_DSPENHMETAFILE  = 0x008E
+	CF_PRIVATEFIRST    = 0x0200
+	CF_PRIVATELAST     = 0x02FF
+	CF_GDIOBJFIRST     = 0x0300
+	CF_GDIOBJLAST      = 0x03FF
+)
+
+// Bitmap compression formats
+const (
+	BI_RGB       = 0
+	BI_RLE8      = 1
+	BI_RLE4      = 2
+	BI_BITFIELDS = 3
+	BI_JPEG      = 4
+	BI_PNG       = 5
+)
+
+// SetDIBitsToDevice fuColorUse
+const (
+	DIB_PAL_COLORS = 1
+	DIB_RGB_COLORS = 0
+)
+
+const (
+	STANDARD_RIGHTS_REQUIRED = 0x000F
+)
+
+// MapVirtualKey maptypes
+const (
+	MAPVK_VK_TO_CHAR   = 2
+	MAPVK_VK_TO_VSC    = 0
+	MAPVK_VSC_TO_VK    = 1
+	MAPVK_VSC_TO_VK_EX = 3
+)
+
+// ReadEventLog Flags
+const (
+	EVENTLOG_SEEK_READ       = 0x0002
+	EVENTLOG_SEQUENTIAL_READ = 0x0001
+	EVENTLOG_FORWARDS_READ   = 0x0004
+	EVENTLOG_BACKWARDS_READ  = 0x0008
+)
+
+// CreateToolhelp32Snapshot flags
+const (
+	TH32CS_SNAPHEAPLIST = 0x00000001
+	TH32CS_SNAPPROCESS  = 0x00000002
+	TH32CS_SNAPTHREAD   = 0x00000004
+	TH32CS_SNAPMODULE   = 0x00000008
+	TH32CS_SNAPMODULE32 = 0x00000010
+	TH32CS_INHERIT      = 0x80000000
+	TH32CS_SNAPALL      = TH32CS_SNAPHEAPLIST | TH32CS_SNAPMODULE | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD
+)
+
+const (
+	MAX_MODULE_NAME32 = 255
+	MAX_PATH          = 260
+)
+
+const (
+	FOREGROUND_BLUE            = 0x0001
+	FOREGROUND_GREEN           = 0x0002
+	FOREGROUND_RED             = 0x0004
+	FOREGROUND_INTENSITY       = 0x0008
+	BACKGROUND_BLUE            = 0x0010
+	BACKGROUND_GREEN           = 0x0020
+	BACKGROUND_RED             = 0x0040
+	BACKGROUND_INTENSITY       = 0x0080
+	COMMON_LVB_LEADING_BYTE    = 0x0100
+	COMMON_LVB_TRAILING_BYTE   = 0x0200
+	COMMON_LVB_GRID_HORIZONTAL = 0x0400
+	COMMON_LVB_GRID_LVERTICAL  = 0x0800
+	COMMON_LVB_GRID_RVERTICAL  = 0x1000
+	COMMON_LVB_REVERSE_VIDEO   = 0x4000
+	COMMON_LVB_UNDERSCORE      = 0x8000
+)
+
+// Flags used by the DWM_BLURBEHIND structure to indicate
+// which of its members contain valid information.
+const (
+	DWM_BB_ENABLE                = 0x00000001 //     A value for the fEnable member has been specified.
+	DWM_BB_BLURREGION            = 0x00000002 //     A value for the hRgnBlur member has been specified.
+	DWM_BB_TRANSITIONONMAXIMIZED = 0x00000004 //     A value for the fTransitionOnMaximized member has been specified.
+)
+
+// Flags used by the DwmEnableComposition  function
+// to change the state of Desktop Window Manager (DWM) composition.
+const (
+	DWM_EC_DISABLECOMPOSITION = 0 //     Disable composition
+	DWM_EC_ENABLECOMPOSITION  = 1 //     Enable composition
+)
+
+// enum-lite implementation for the following constant structure
+type DWM_SHOWCONTACT int32
+
+const (
+	DWMSC_DOWN      = 0x00000001
+	DWMSC_UP        = 0x00000002
+	DWMSC_DRAG      = 0x00000004
+	DWMSC_HOLD      = 0x00000008
+	DWMSC_PENBARREL = 0x00000010
+	DWMSC_NONE      = 0x00000000
+	DWMSC_ALL       = 0xFFFFFFFF
+)
+
+// enum-lite implementation for the following constant structure
+type DWM_SOURCE_FRAME_SAMPLING int32
+
+// TODO: need to verify this construction
+// Flags used by the DwmSetPresentParameters function
+// to specify the frame sampling type
+const (
+	DWM_SOURCE_FRAME_SAMPLING_POINT = iota + 1
+	DWM_SOURCE_FRAME_SAMPLING_COVERAGE
+	DWM_SOURCE_FRAME_SAMPLING_LAST
+)
+
+// Flags used by the DWM_THUMBNAIL_PROPERTIES structure to
+// indicate which of its members contain valid information.
+const (
+	DWM_TNP_RECTDESTINATION      = 0x00000001 //    A value for the rcDestination member has been specified
+	DWM_TNP_RECTSOURCE           = 0x00000002 //    A value for the rcSource member has been specified
+	DWM_TNP_OPACITY              = 0x00000004 //    A value for the opacity member has been specified
+	DWM_TNP_VISIBLE              = 0x00000008 //    A value for the fVisible member has been specified
+	DWM_TNP_SOURCECLIENTAREAONLY = 0x00000010 //    A value for the fSourceClientAreaOnly member has been specified
+)
+
+// enum-lite implementation for the following constant structure
+type DWMFLIP3DWINDOWPOLICY int32
+
+// TODO: need to verify this construction
+// Flags used by the DwmSetWindowAttribute function
+// to specify the Flip3D window policy
+const (
+	DWMFLIP3D_DEFAULT = iota + 1
+	DWMFLIP3D_EXCLUDEBELOW
+	DWMFLIP3D_EXCLUDEABOVE
+	DWMFLIP3D_LAST
+)
+
+// enum-lite implementation for the following constant structure
+type DWMNCRENDERINGPOLICY int32
+
+// TODO: need to verify this construction
+// Flags used by the DwmSetWindowAttribute function
+// to specify the non-client area rendering policy
+const (
+	DWMNCRP_USEWINDOWSTYLE = iota + 1
+	DWMNCRP_DISABLED
+	DWMNCRP_ENABLED
+	DWMNCRP_LAST
+)
+
+// enum-lite implementation for the following constant structure
+type DWMTRANSITION_OWNEDWINDOW_TARGET int32
+
+const (
+	DWMTRANSITION_OWNEDWINDOW_NULL       = -1
+	DWMTRANSITION_OWNEDWINDOW_REPOSITION = 0
+)
+
+// enum-lite implementation for the following constant structure
+type DWMWINDOWATTRIBUTE int32
+
+// TODO: need to verify this construction
+// Flags used by the DwmGetWindowAttribute and DwmSetWindowAttribute functions
+// to specify window attributes for non-client rendering
+const (
+	DWMWA_NCRENDERING_ENABLED = iota + 1
+	DWMWA_NCRENDERING_POLICY
+	DWMWA_TRANSITIONS_FORCEDISABLED
+	DWMWA_ALLOW_NCPAINT
+	DWMWA_CAPTION_BUTTON_BOUNDS
+	DWMWA_NONCLIENT_RTL_LAYOUT
+	DWMWA_FORCE_ICONIC_REPRESENTATION
+	DWMWA_FLIP3D_POLICY
+	DWMWA_EXTENDED_FRAME_BOUNDS
+	DWMWA_HAS_ICONIC_BITMAP
+	DWMWA_DISALLOW_PEEK
+	DWMWA_EXCLUDED_FROM_PEEK
+	DWMWA_CLOAK
+	DWMWA_CLOAKED
+	DWMWA_FREEZE_REPRESENTATION
+	DWMWA_LAST
+)
+
+// enum-lite implementation for the following constant structure
+type GESTURE_TYPE int32
+
+// TODO: use iota?
+// Identifies the gesture type
+const (
+	GT_PEN_TAP                 = 0
+	GT_PEN_DOUBLETAP           = 1
+	GT_PEN_RIGHTTAP            = 2
+	GT_PEN_PRESSANDHOLD        = 3
+	GT_PEN_PRESSANDHOLDABORT   = 4
+	GT_TOUCH_TAP               = 5
+	GT_TOUCH_DOUBLETAP         = 6
+	GT_TOUCH_RIGHTTAP          = 7
+	GT_TOUCH_PRESSANDHOLD      = 8
+	GT_TOUCH_PRESSANDHOLDABORT = 9
+	GT_TOUCH_PRESSANDTAP       = 10
+)
+
+// Icons
+const (
+	ICON_SMALL  = 0
+	ICON_BIG    = 1
+	ICON_SMALL2 = 2
+)
+
+const (
+	SIZE_RESTORED  = 0
+	SIZE_MINIMIZED = 1
+	SIZE_MAXIMIZED = 2
+	SIZE_MAXSHOW   = 3
+	SIZE_MAXHIDE   = 4
+)
+
+// XButton values
+const (
+	XBUTTON1 = 1
+	XBUTTON2 = 2
+)
+
+// Devmode
+const (
+	DM_SPECVERSION = 0x0401
+
+	DM_ORIENTATION        = 0x00000001
+	DM_PAPERSIZE          = 0x00000002
+	DM_PAPERLENGTH        = 0x00000004
+	DM_PAPERWIDTH         = 0x00000008
+	DM_SCALE              = 0x00000010
+	DM_POSITION           = 0x00000020
+	DM_NUP                = 0x00000040
+	DM_DISPLAYORIENTATION = 0x00000080
+	DM_COPIES             = 0x00000100
+	DM_DEFAULTSOURCE      = 0x00000200
+	DM_PRINTQUALITY       = 0x00000400
+	DM_COLOR              = 0x00000800
+	DM_DUPLEX             = 0x00001000
+	DM_YRESOLUTION        = 0x00002000
+	DM_TTOPTION           = 0x00004000
+	DM_COLLATE            = 0x00008000
+	DM_FORMNAME           = 0x00010000
+	DM_LOGPIXELS          = 0x00020000
+	DM_BITSPERPEL         = 0x00040000
+	DM_PELSWIDTH          = 0x00080000
+	DM_PELSHEIGHT         = 0x00100000
+	DM_DISPLAYFLAGS       = 0x00200000
+	DM_DISPLAYFREQUENCY   = 0x00400000
+	DM_ICMMETHOD          = 0x00800000
+	DM_ICMINTENT          = 0x01000000
+	DM_MEDIATYPE          = 0x02000000
+	DM_DITHERTYPE         = 0x04000000
+	DM_PANNINGWIDTH       = 0x08000000
+	DM_PANNINGHEIGHT      = 0x10000000
+	DM_DISPLAYFIXEDOUTPUT = 0x20000000
+)
+
+// ChangeDisplaySettings
+const (
+	CDS_UPDATEREGISTRY  = 0x00000001
+	CDS_TEST            = 0x00000002
+	CDS_FULLSCREEN      = 0x00000004
+	CDS_GLOBAL          = 0x00000008
+	CDS_SET_PRIMARY     = 0x00000010
+	CDS_VIDEOPARAMETERS = 0x00000020
+	CDS_RESET           = 0x40000000
+	CDS_NORESET         = 0x10000000
+
+	DISP_CHANGE_SUCCESSFUL  = 0
+	DISP_CHANGE_RESTART     = 1
+	DISP_CHANGE_FAILED      = -1
+	DISP_CHANGE_BADMODE     = -2
+	DISP_CHANGE_NOTUPDATED  = -3
+	DISP_CHANGE_BADFLAGS    = -4
+	DISP_CHANGE_BADPARAM    = -5
+	DISP_CHANGE_BADDUALVIEW = -6
+)
+
+const (
+	ENUM_CURRENT_SETTINGS  = 0xFFFFFFFF
+	ENUM_REGISTRY_SETTINGS = 0xFFFFFFFE
+)
+
+// PIXELFORMATDESCRIPTOR
+const (
+	PFD_TYPE_RGBA       = 0
+	PFD_TYPE_COLORINDEX = 1
+
+	PFD_MAIN_PLANE     = 0
+	PFD_OVERLAY_PLANE  = 1
+	PFD_UNDERLAY_PLANE = -1
+
+	PFD_DOUBLEBUFFER         = 0x00000001
+	PFD_STEREO               = 0x00000002
+	PFD_DRAW_TO_WINDOW       = 0x00000004
+	PFD_DRAW_TO_BITMAP       = 0x00000008
+	PFD_SUPPORT_GDI          = 0x00000010
+	PFD_SUPPORT_OPENGL       = 0x00000020
+	PFD_GENERIC_FORMAT       = 0x00000040
+	PFD_NEED_PALETTE         = 0x00000080
+	PFD_NEED_SYSTEM_PALETTE  = 0x00000100
+	PFD_SWAP_EXCHANGE        = 0x00000200
+	PFD_SWAP_COPY            = 0x00000400
+	PFD_SWAP_LAYER_BUFFERS   = 0x00000800
+	PFD_GENERIC_ACCELERATED  = 0x00001000
+	PFD_SUPPORT_DIRECTDRAW   = 0x00002000
+	PFD_DIRECT3D_ACCELERATED = 0x00004000
+	PFD_SUPPORT_COMPOSITION  = 0x00008000
+
+	PFD_DEPTH_DONTCARE        = 0x20000000
+	PFD_DOUBLEBUFFER_DONTCARE = 0x40000000
+	PFD_STEREO_DONTCARE       = 0x80000000
+)
+
+const (
+	INPUT_MOUSE    = 0
+	INPUT_KEYBOARD = 1
+	INPUT_HARDWARE = 2
+)
+
+const (
+	MOUSEEVENTF_ABSOLUTE        = 0x8000
+	MOUSEEVENTF_HWHEEL          = 0x01000
+	MOUSEEVENTF_MOVE            = 0x0001
+	MOUSEEVENTF_MOVE_NOCOALESCE = 0x2000
+	MOUSEEVENTF_LEFTDOWN        = 0x0002
+	MOUSEEVENTF_LEFTUP          = 0x0004
+	MOUSEEVENTF_RIGHTDOWN       = 0x0008
+	MOUSEEVENTF_RIGHTUP         = 0x0010
+	MOUSEEVENTF_MIDDLEDOWN      = 0x0020
+	MOUSEEVENTF_MIDDLEUP        = 0x0040
+	MOUSEEVENTF_VIRTUALDESK     = 0x4000
+	MOUSEEVENTF_WHEEL           = 0x0800
+	MOUSEEVENTF_XDOWN           = 0x0080
+	MOUSEEVENTF_XUP             = 0x0100
+)
+
+// Windows Hooks (WH_*)
+// http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx
+const (
+	WH_CALLWNDPROC     = 4
+	WH_CALLWNDPROCRET  = 12
+	WH_CBT             = 5
+	WH_DEBUG           = 9
+	WH_FOREGROUNDIDLE  = 11
+	WH_GETMESSAGE      = 3
+	WH_JOURNALPLAYBACK = 1
+	WH_JOURNALRECORD   = 0
+	WH_KEYBOARD        = 2
+	WH_KEYBOARD_LL     = 13
+	WH_MOUSE           = 7
+	WH_MOUSE_LL        = 14
+	WH_MSGFILTER       = -1
+	WH_SHELL           = 10
+	WH_SYSMSGFILTER    = 6
+)
+
+const (
+	MEM_COMMIT     = 0x00001000
+	MEM_RESERVE    = 0x00002000
+	MEM_RESET      = 0x00080000
+	MEM_RESET_UNDO = 0x1000000
+
+	MEM_LARGE_PAGES = 0x20000000
+	MEM_PHYSICAL    = 0x00400000
+	MEM_TOP_DOWN    = 0x00100000
+
+	MEM_DECOMMIT = 0x4000
+	MEM_RELEASE  = 0x8000
+)
+
+const (
+	PROCESS_CREATE_PROCESS            = 0x0080
+	PROCESS_CREATE_THREAD             = 0x0002
+	PROCESS_DUP_HANDLE                = 0x0040
+	PROCESS_QUERY_INFORMATION         = 0x0400
+	PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
+	PROCESS_SET_INFORMATION           = 0x0200
+	PROCESS_SET_QUOTA                 = 0x0100
+	PROCESS_SUSPEND_RESUME            = 0x0800
+	PROCESS_TERMINATE                 = 0x0001
+	PROCESS_VM_OPERATION              = 0x0008
+	PROCESS_VM_READ                   = 0x0010
+	PROCESS_VM_WRITE                  = 0x0020
+	SYNCHRONIZE                       = 0x00100000
+)
+
+const (
+	PAGE_EXECUTE           = 0x10
+	PAGE_EXECUTE_READ      = 0x20
+	PAGE_EXECUTE_READWRITE = 0x40
+	PAGE_EXECUTE_WRITECOPY = 0x80
+	PAGE_NOACCESS          = 0x01
+	PAGE_READWRITE         = 0x04
+	PAGE_WRITECOPY         = 0x08
+	PAGE_TARGETS_INVALID   = 0x40000000
+	PAGE_TARGETS_NO_UPDATE = 0x40000000
+)
+
+// SendMessageTimeout Flags
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms644952(v=vs.85).aspx
+const (
+	SMTO_ABORTIFHUNG        = 0x0002
+	SMTO_BLOCK              = 0x0001
+	SMTO_NORMAL             = 0x0000
+	SMTO_NOTIMEOUTIFNOTHUNG = 0x0008
+	SMTO_ERRORONEXIT        = 0x0020
+)
+
+// RedrawWindow Flags
+const (
+	RDW_ERASE = 4
+	RDW_ALLCHILDREN = 0x80
+	RDW_ERASENOW = 0x200
+	RDW_FRAME = 0x400
+	RDW_INTERNALPAINT = 2
+	RDW_INVALIDATE = 1
+	RDW_NOCHILDREN = 0x40
+	RDW_NOERASE = 0x20
+	RDW_NOFRAME = 0x800
+	RDW_NOINTERNALPAINT = 0x10
+	RDW_UPDATENOW = 0x100
+	RDW_VALIDATE = 8
+)
diff --git a/packages/w32/create_process.go b/packages/w32/create_process.go
new file mode 100644
index 00000000..9caf9ffc
--- /dev/null
+++ b/packages/w32/create_process.go
@@ -0,0 +1,152 @@
+// Copyright 2010-2012 The W32 Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package w32
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+var (
+	kernel32 = syscall.NewLazyDLL("kernel32.dll")
+
+	procCreateProcessW      = kernel32.NewProc("CreateProcessW")
+	procTerminateProcess    = kernel32.NewProc("TerminateProcess")
+	procGetExitCodeProcess  = kernel32.NewProc("GetExitCodeProcess")
+	procWaitForSingleObject = kernel32.NewProc("WaitForSingleObject")
+)
+
+// WINBASEAPI WINBOOL WINAPI
+// CreateProcessW (
+// LPCWSTR lpApplicationName,
+// LPWSTR lpCommandLine,
+// LPSECURITY_ATTRIBUTES lpProcessAttributes,
+// LPSECURITY_ATTRIBUTES lpThreadAttributes
+// WINBOOL bInheritHandles
+// DWORD dwCreationFlags
+// LPVOID lpEnvironment
+// LPCWSTR lpCurrentDirectory
+// LPSTARTUPINFOW lpStartupInfo
+// LPPROCESS_INFORMATION lpProcessInformation
+//);
+func CreateProcessW(
+	lpApplicationName, lpCommandLine string,
+	lpProcessAttributes, lpThreadAttributes *SECURITY_ATTRIBUTES,
+	bInheritHandles BOOL,
+	dwCreationFlags uint32,
+	lpEnvironment unsafe.Pointer,
+	lpCurrentDirectory string,
+	lpStartupInfo *STARTUPINFOW,
+	lpProcessInformation *PROCESS_INFORMATION,
+) (e error) {
+
+	var lpAN, lpCL, lpCD *uint16
+	if len(lpApplicationName) > 0 {
+		lpAN, e = syscall.UTF16PtrFromString(lpApplicationName)
+		if e != nil {
+			return
+		}
+	}
+	if len(lpCommandLine) > 0 {
+		lpCL, e = syscall.UTF16PtrFromString(lpCommandLine)
+		if e != nil {
+			return
+		}
+	}
+	if len(lpCurrentDirectory) > 0 {
+		lpCD, e = syscall.UTF16PtrFromString(lpCurrentDirectory)
+		if e != nil {
+			return
+		}
+	}
+
+	ret, _, lastErr := procCreateProcessW.Call(
+		uintptr(unsafe.Pointer(lpAN)),
+		uintptr(unsafe.Pointer(lpCL)),
+		uintptr(unsafe.Pointer(lpProcessAttributes)),
+		uintptr(unsafe.Pointer(lpProcessInformation)),
+		uintptr(bInheritHandles),
+		uintptr(dwCreationFlags),
+		uintptr(lpEnvironment),
+		uintptr(unsafe.Pointer(lpCD)),
+		uintptr(unsafe.Pointer(lpStartupInfo)),
+		uintptr(unsafe.Pointer(lpProcessInformation)),
+	)
+
+	if ret == 0 {
+		e = lastErr
+	}
+
+	return
+}
+
+func CreateProcessQuick(cmd string) (pi PROCESS_INFORMATION, e error) {
+	si := &STARTUPINFOW{}
+	e = CreateProcessW(
+		"",
+		cmd,
+		nil,
+		nil,
+		0,
+		0,
+		unsafe.Pointer(nil),
+		"",
+		si,
+		&pi,
+	)
+	return
+}
+
+func TerminateProcess(hProcess HANDLE, exitCode uint32) (e error) {
+	ret, _, lastErr := procTerminateProcess.Call(
+		uintptr(hProcess),
+		uintptr(exitCode),
+	)
+
+	if ret == 0 {
+		e = lastErr
+	}
+
+	return
+}
+
+func GetExitCodeProcess(hProcess HANDLE) (code uintptr, e error) {
+	ret, _, lastErr := procGetExitCodeProcess.Call(
+		uintptr(hProcess),
+		uintptr(unsafe.Pointer(&code)),
+	)
+
+	if ret == 0 {
+		e = lastErr
+	}
+
+	return
+}
+
+// DWORD WINAPI WaitForSingleObject(
+//   _In_ HANDLE hHandle,
+//   _In_ DWORD  dwMilliseconds
+// );
+
+func WaitForSingleObject(hHandle HANDLE, msecs uint32) (ok bool, e error) {
+
+	ret, _, lastErr := procWaitForSingleObject.Call(
+		uintptr(hHandle),
+		uintptr(msecs),
+	)
+
+	if ret == WAIT_OBJECT_0 {
+		ok = true
+		return
+	}
+
+	// don't set e for timeouts, or it will be ERROR_SUCCESS which is
+	// confusing
+	if ret != WAIT_TIMEOUT {
+		e = lastErr
+	}
+	return
+
+}
diff --git a/packages/w32/create_process_constants.go b/packages/w32/create_process_constants.go
new file mode 100644
index 00000000..c37d7e5f
--- /dev/null
+++ b/packages/w32/create_process_constants.go
@@ -0,0 +1,9 @@
+package w32
+
+const (
+	WAIT_ABANDONED = 0x00000080
+	WAIT_OBJECT_0  = 0x00000000
+	WAIT_TIMEOUT   = 0x00000102
+	WAIT_FAILED    = 0xFFFFFFFF
+	INFINITE       = 0xFFFFFFFF
+)
diff --git a/packages/w32/create_process_typedef.go b/packages/w32/create_process_typedef.go
new file mode 100644
index 00000000..df059729
--- /dev/null
+++ b/packages/w32/create_process_typedef.go
@@ -0,0 +1,68 @@
+package w32
+
+// typedef struct _PROCESS_INFORMATION {
+//   HANDLE hProcess;
+//   HANDLE hThread;
+//   DWORD dwProcessId;
+//   DWORD dwThreadId;
+// } PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION;
+
+type PROCESS_INFORMATION struct {
+	Process   HANDLE
+	Thread    HANDLE
+	ProcessId uint32
+	ThreadId  uint32
+}
+
+// typedef struct _STARTUPINFOW {
+//   DWORD cb;
+//   LPWSTR lpReserved;
+//   LPWSTR lpDesktop;
+//   LPWSTR lpTitle;
+//   DWORD dwX;
+//   DWORD dwY;
+//   DWORD dwXSize;
+//   DWORD dwYSize;
+//   DWORD dwXCountChars;
+//   DWORD dwYCountChars;
+//   DWORD dwFillAttribute;
+//   DWORD dwFlags;
+//   WORD wShowWindow;
+//   WORD cbReserved2;
+//   LPBYTE lpReserved2;
+//   HANDLE hStdInput;
+//   HANDLE hStdOutput;
+//   HANDLE hStdError;
+// } STARTUPINFOW, *LPSTARTUPINFOW;
+
+type STARTUPINFOW struct {
+	cb            uint32
+	_             *uint16
+	Desktop       *uint16
+	Title         *uint16
+	X             uint32
+	Y             uint32
+	XSize         uint32
+	YSize         uint32
+	XCountChars   uint32
+	YCountChars   uint32
+	FillAttribute uint32
+	Flags         uint32
+	ShowWindow    uint16
+	_             uint16
+	_             *uint8
+	StdInput      HANDLE
+	StdOutput     HANDLE
+	StdError      HANDLE
+}
+
+// combase!_SECURITY_ATTRIBUTES
+//    +0x000 nLength          : Uint4B
+//    +0x008 lpSecurityDescriptor : Ptr64 Void
+//    +0x010 bInheritHandle   : Int4B
+
+type SECURITY_ATTRIBUTES struct {
+	Length             uint32
+	SecurityDescriptor uintptr
+	InheritHandle      BOOL
+}
diff --git a/packages/w32/dwmapi.go b/packages/w32/dwmapi.go
new file mode 100644
index 00000000..eb656d18
--- /dev/null
+++ b/packages/w32/dwmapi.go
@@ -0,0 +1,254 @@
+// Copyright 2010-2012 The W32 Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package w32
+
+import (
+	"fmt"
+	"syscall"
+	"unsafe"
+)
+
+// DEFINED IN THE DWM API BUT NOT IMPLEMENTED BY MS:
+// DwmAttachMilContent
+// DwmDetachMilContent
+// DwmEnableComposition
+// DwmGetGraphicsStreamClient
+// DwmGetGraphicsStreamTransformHint
+
+var (
+	moddwmapi = syscall.NewLazyDLL("dwmapi.dll")
+
+	procDwmDefWindowProc                 = moddwmapi.NewProc("DwmDefWindowProc")
+	procDwmEnableBlurBehindWindow        = moddwmapi.NewProc("DwmEnableBlurBehindWindow")
+	procDwmEnableMMCSS                   = moddwmapi.NewProc("DwmEnableMMCSS")
+	procDwmExtendFrameIntoClientArea     = moddwmapi.NewProc("DwmExtendFrameIntoClientArea")
+	procDwmFlush                         = moddwmapi.NewProc("DwmFlush")
+	procDwmGetColorizationColor          = moddwmapi.NewProc("DwmGetColorizationColor")
+	procDwmGetCompositionTimingInfo      = moddwmapi.NewProc("DwmGetCompositionTimingInfo")
+	procDwmGetTransportAttributes        = moddwmapi.NewProc("DwmGetTransportAttributes")
+	procDwmGetWindowAttribute            = moddwmapi.NewProc("DwmGetWindowAttribute")
+	procDwmInvalidateIconicBitmaps       = moddwmapi.NewProc("DwmInvalidateIconicBitmaps")
+	procDwmIsCompositionEnabled          = moddwmapi.NewProc("DwmIsCompositionEnabled")
+	procDwmModifyPreviousDxFrameDuration = moddwmapi.NewProc("DwmModifyPreviousDxFrameDuration")
+	procDwmQueryThumbnailSourceSize      = moddwmapi.NewProc("DwmQueryThumbnailSourceSize")
+	procDwmRegisterThumbnail             = moddwmapi.NewProc("DwmRegisterThumbnail")
+	procDwmRenderGesture                 = moddwmapi.NewProc("DwmRenderGesture")
+	procDwmSetDxFrameDuration            = moddwmapi.NewProc("DwmSetDxFrameDuration")
+	procDwmSetIconicLivePreviewBitmap    = moddwmapi.NewProc("DwmSetIconicLivePreviewBitmap")
+	procDwmSetIconicThumbnail            = moddwmapi.NewProc("DwmSetIconicThumbnail")
+	procDwmSetPresentParameters          = moddwmapi.NewProc("DwmSetPresentParameters")
+	procDwmSetWindowAttribute            = moddwmapi.NewProc("DwmSetWindowAttribute")
+	procDwmShowContact                   = moddwmapi.NewProc("DwmShowContact")
+	procDwmTetherContact                 = moddwmapi.NewProc("DwmTetherContact")
+	procDwmTransitionOwnedWindow         = moddwmapi.NewProc("DwmTransitionOwnedWindow")
+	procDwmUnregisterThumbnail           = moddwmapi.NewProc("DwmUnregisterThumbnail")
+	procDwmUpdateThumbnailProperties     = moddwmapi.NewProc("DwmUpdateThumbnailProperties")
+)
+
+func DwmDefWindowProc(hWnd HWND, msg uint, wParam, lParam uintptr) (bool, uint) {
+	var result uint
+	ret, _, _ := procDwmDefWindowProc.Call(
+		uintptr(hWnd),
+		uintptr(msg),
+		wParam,
+		lParam,
+		uintptr(unsafe.Pointer(&result)))
+	return ret != 0, result
+}
+
+func DwmEnableBlurBehindWindow(hWnd HWND, pBlurBehind *DWM_BLURBEHIND) HRESULT {
+	ret, _, _ := procDwmEnableBlurBehindWindow.Call(
+		uintptr(hWnd),
+		uintptr(unsafe.Pointer(pBlurBehind)))
+	return HRESULT(ret)
+}
+
+func DwmEnableMMCSS(fEnableMMCSS bool) HRESULT {
+	ret, _, _ := procDwmEnableMMCSS.Call(
+		uintptr(BoolToBOOL(fEnableMMCSS)))
+	return HRESULT(ret)
+}
+
+func DwmExtendFrameIntoClientArea(hWnd HWND, pMarInset *MARGINS) HRESULT {
+	ret, _, _ := procDwmExtendFrameIntoClientArea.Call(
+		uintptr(hWnd),
+		uintptr(unsafe.Pointer(pMarInset)))
+	return HRESULT(ret)
+}
+
+func DwmFlush() HRESULT {
+	ret, _, _ := procDwmFlush.Call()
+	return HRESULT(ret)
+}
+
+func DwmGetColorizationColor(pcrColorization *uint32, pfOpaqueBlend *BOOL) HRESULT {
+	ret, _, _ := procDwmGetColorizationColor.Call(
+		uintptr(unsafe.Pointer(pcrColorization)),
+		uintptr(unsafe.Pointer(pfOpaqueBlend)))
+	return HRESULT(ret)
+}
+
+func DwmGetCompositionTimingInfo(hWnd HWND, pTimingInfo *DWM_TIMING_INFO) HRESULT {
+	ret, _, _ := procDwmGetCompositionTimingInfo.Call(
+		uintptr(hWnd),
+		uintptr(unsafe.Pointer(pTimingInfo)))
+	return HRESULT(ret)
+}
+
+func DwmGetTransportAttributes(pfIsRemoting *BOOL, pfIsConnected *BOOL, pDwGeneration *uint32) HRESULT {
+	ret, _, _ := procDwmGetTransportAttributes.Call(
+		uintptr(unsafe.Pointer(pfIsRemoting)),
+		uintptr(unsafe.Pointer(pfIsConnected)),
+		uintptr(unsafe.Pointer(pDwGeneration)))
+	return HRESULT(ret)
+}
+
+// TODO: verify handling of variable arguments
+func DwmGetWindowAttribute(hWnd HWND, dwAttribute uint32) (pAttribute interface{}, result HRESULT) {
+	var pvAttribute, pvAttrSize uintptr
+	switch dwAttribute {
+	case DWMWA_NCRENDERING_ENABLED:
+		v := new(BOOL)
+		pAttribute = v
+		pvAttribute = uintptr(unsafe.Pointer(v))
+		pvAttrSize = unsafe.Sizeof(*v)
+	case DWMWA_CAPTION_BUTTON_BOUNDS, DWMWA_EXTENDED_FRAME_BOUNDS:
+		v := new(RECT)
+		pAttribute = v
+		pvAttribute = uintptr(unsafe.Pointer(v))
+		pvAttrSize = unsafe.Sizeof(*v)
+	case DWMWA_CLOAKED:
+		panic(fmt.Sprintf("DwmGetWindowAttribute(%d) is not currently supported.", dwAttribute))
+	default:
+		panic(fmt.Sprintf("DwmGetWindowAttribute(%d) is not valid.", dwAttribute))
+	}
+
+	ret, _, _ := procDwmGetWindowAttribute.Call(
+		uintptr(hWnd),
+		uintptr(dwAttribute),
+		pvAttribute,
+		pvAttrSize)
+	result = HRESULT(ret)
+	return
+}
+
+func DwmInvalidateIconicBitmaps(hWnd HWND) HRESULT {
+	ret, _, _ := procDwmInvalidateIconicBitmaps.Call(
+		uintptr(hWnd))
+	return HRESULT(ret)
+}
+
+func DwmIsCompositionEnabled(pfEnabled *BOOL) HRESULT {
+	ret, _, _ := procDwmIsCompositionEnabled.Call(
+		uintptr(unsafe.Pointer(pfEnabled)))
+	return HRESULT(ret)
+}
+
+func DwmModifyPreviousDxFrameDuration(hWnd HWND, cRefreshes int, fRelative bool) HRESULT {
+	ret, _, _ := procDwmModifyPreviousDxFrameDuration.Call(
+		uintptr(hWnd),
+		uintptr(cRefreshes),
+		uintptr(BoolToBOOL(fRelative)))
+	return HRESULT(ret)
+}
+
+func DwmQueryThumbnailSourceSize(hThumbnail HTHUMBNAIL, pSize *SIZE) HRESULT {
+	ret, _, _ := procDwmQueryThumbnailSourceSize.Call(
+		uintptr(hThumbnail),
+		uintptr(unsafe.Pointer(pSize)))
+	return HRESULT(ret)
+}
+
+func DwmRegisterThumbnail(hWndDestination HWND, hWndSource HWND, phThumbnailId *HTHUMBNAIL) HRESULT {
+	ret, _, _ := procDwmRegisterThumbnail.Call(
+		uintptr(hWndDestination),
+		uintptr(hWndSource),
+		uintptr(unsafe.Pointer(phThumbnailId)))
+	return HRESULT(ret)
+}
+
+func DwmRenderGesture(gt GESTURE_TYPE, cContacts uint, pdwPointerID *uint32, pPoints *POINT) {
+	procDwmRenderGesture.Call(
+		uintptr(gt),
+		uintptr(cContacts),
+		uintptr(unsafe.Pointer(pdwPointerID)),
+		uintptr(unsafe.Pointer(pPoints)))
+	return
+}
+
+func DwmSetDxFrameDuration(hWnd HWND, cRefreshes int) HRESULT {
+	ret, _, _ := procDwmSetDxFrameDuration.Call(
+		uintptr(hWnd),
+		uintptr(cRefreshes))
+	return HRESULT(ret)
+}
+
+func DwmSetIconicLivePreviewBitmap(hWnd HWND, hbmp HBITMAP, pptClient *POINT, dwSITFlags uint32) HRESULT {
+	ret, _, _ := procDwmSetIconicLivePreviewBitmap.Call(
+		uintptr(hWnd),
+		uintptr(hbmp),
+		uintptr(unsafe.Pointer(pptClient)),
+		uintptr(dwSITFlags))
+	return HRESULT(ret)
+}
+
+func DwmSetIconicThumbnail(hWnd HWND, hbmp HBITMAP, dwSITFlags uint32) HRESULT {
+	ret, _, _ := procDwmSetIconicThumbnail.Call(
+		uintptr(hWnd),
+		uintptr(hbmp),
+		uintptr(dwSITFlags))
+	return HRESULT(ret)
+}
+
+func DwmSetPresentParameters(hWnd HWND, pPresentParams *DWM_PRESENT_PARAMETERS) HRESULT {
+	ret, _, _ := procDwmSetPresentParameters.Call(
+		uintptr(hWnd),
+		uintptr(unsafe.Pointer(pPresentParams)))
+	return HRESULT(ret)
+}
+
+func DwmSetWindowAttribute(hWnd HWND, dwAttribute uint32, pvAttribute LPCVOID, cbAttribute uint32) HRESULT {
+	ret, _, _ := procDwmSetWindowAttribute.Call(
+		uintptr(hWnd),
+		uintptr(dwAttribute),
+		uintptr(pvAttribute),
+		uintptr(cbAttribute))
+	return HRESULT(ret)
+}
+
+func DwmShowContact(dwPointerID uint32, eShowContact DWM_SHOWCONTACT) {
+	procDwmShowContact.Call(
+		uintptr(dwPointerID),
+		uintptr(eShowContact))
+	return
+}
+
+func DwmTetherContact(dwPointerID uint32, fEnable bool, ptTether POINT) {
+	procDwmTetherContact.Call(
+		uintptr(dwPointerID),
+		uintptr(BoolToBOOL(fEnable)),
+		uintptr(unsafe.Pointer(&ptTether)))
+	return
+}
+
+func DwmTransitionOwnedWindow(hWnd HWND, target DWMTRANSITION_OWNEDWINDOW_TARGET) {
+	procDwmTransitionOwnedWindow.Call(
+		uintptr(hWnd),
+		uintptr(target))
+	return
+}
+
+func DwmUnregisterThumbnail(hThumbnailId HTHUMBNAIL) HRESULT {
+	ret, _, _ := procDwmUnregisterThumbnail.Call(
+		uintptr(hThumbnailId))
+	return HRESULT(ret)
+}
+
+func DwmUpdateThumbnailProperties(hThumbnailId HTHUMBNAIL, ptnProperties *DWM_THUMBNAIL_PROPERTIES) HRESULT {
+	ret, _, _ := procDwmUpdateThumbnailProperties.Call(
+		uintptr(hThumbnailId),
+		uintptr(unsafe.Pointer(ptnProperties)))
+	return HRESULT(ret)
+}
diff --git a/packages/w32/fork.go b/packages/w32/fork.go
new file mode 100644
index 00000000..b5543b95
--- /dev/null
+++ b/packages/w32/fork.go
@@ -0,0 +1,174 @@
+// Copyright 2010-2012 The W32 Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package w32
+
+// #include <stdlib.h>
+//import (
+//	"C"
+//)
+
+// Based on C code found here https://gist.github.com/juntalis/4366916
+// Original code license:
+/*
+ * fork.c
+ * Experimental fork() on Windows.  Requires NT 6 subsystem or
+ * newer.
+ *
+ * Copyright (c) 2012 William Pitcock <nenolod@dereferenced.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * This software is provided 'as is' and without any warranty, express or
+ * implied.  In no event shall the authors be liable for any damages arising
+ * from the use of this software.
+ */
+
+import (
+	"fmt"
+	"syscall"
+	"unsafe"
+)
+
+var (
+	ntdll = syscall.NewLazyDLL("ntdll.dll")
+
+	procRtlCloneUserProcess = ntdll.NewProc("RtlCloneUserProcess")
+	procAllocConsole        = modkernel32.NewProc("AllocConsole")
+	procOpenProcess         = modkernel32.NewProc("OpenProcess")
+	procOpenThread          = modkernel32.NewProc("OpenThread")
+	procResumeThread        = modkernel32.NewProc("ResumeThread")
+)
+
+func OpenProcess(desiredAccess int, inheritHandle bool, processId uintptr) (h HANDLE, e error) {
+	inherit := uintptr(0)
+	if inheritHandle {
+		inherit = 1
+	}
+
+	ret, _, lastErr := procOpenProcess.Call(
+		uintptr(desiredAccess),
+		inherit,
+		uintptr(processId),
+	)
+
+	if ret == 0 {
+		e = lastErr
+	}
+
+	h = HANDLE(ret)
+	return
+}
+
+func OpenThread(desiredAccess int, inheritHandle bool, threadId uintptr) (h HANDLE, e error) {
+	inherit := uintptr(0)
+	if inheritHandle {
+		inherit = 1
+	}
+
+	ret, _, lastErr := procOpenThread.Call(
+		uintptr(desiredAccess),
+		inherit,
+		uintptr(threadId),
+	)
+
+	if ret == 0 {
+		e = lastErr
+	}
+
+	h = HANDLE(ret)
+	return
+}
+
+// DWORD WINAPI ResumeThread(
+//   _In_ HANDLE hThread
+// );
+func ResumeThread(ht HANDLE) (e error) {
+
+	ret, _, lastErr := procResumeThread.Call(
+		uintptr(ht),
+	)
+	if ret == ^uintptr(0) { // -1
+		e = lastErr
+	}
+	return
+}
+
+// BOOL WINAPI AllocConsole(void);
+func AllocConsole() (e error) {
+	ret, _, lastErr := procAllocConsole.Call()
+	if ret != ERROR_SUCCESS {
+		e = lastErr
+	}
+	return
+}
+
+// NTSYSAPI
+// NTSTATUS
+// NTAPI RtlCloneUserProcess  (
+//   _In_ ULONG  ProcessFlags,
+//   _In_opt_ PSECURITY_DESCRIPTOR  ProcessSecurityDescriptor,
+//   _In_opt_ PSECURITY_DESCRIPTOR  ThreadSecurityDescriptor,
+//   _In_opt_ HANDLE  DebugPort,
+//   _Out_ PRTL_USER_PROCESS_INFORMATION  ProcessInformation
+//  )
+
+func RtlCloneUserProcess(
+	ProcessFlags uint32,
+	ProcessSecurityDescriptor, ThreadSecurityDescriptor *SECURITY_DESCRIPTOR, // in advapi32_typedef.go
+	DebugPort HANDLE,
+	ProcessInformation *RTL_USER_PROCESS_INFORMATION,
+) (status uintptr) {
+
+	status, _, _ = procRtlCloneUserProcess.Call(
+		uintptr(ProcessFlags),
+		uintptr(unsafe.Pointer(ProcessSecurityDescriptor)),
+		uintptr(unsafe.Pointer(ThreadSecurityDescriptor)),
+		uintptr(DebugPort),
+		uintptr(unsafe.Pointer(ProcessInformation)),
+	)
+
+	return
+}
+
+// Fork creates a clone of the current process using the undocumented
+// RtlCloneUserProcess call in ntdll, similar to unix fork(). The
+// return value in the parent is the child PID. In the child it is 0.
+func Fork() (pid uintptr, e error) {
+
+	pi := &RTL_USER_PROCESS_INFORMATION{}
+
+	ret := RtlCloneUserProcess(
+		RTL_CLONE_PROCESS_FLAGS_CREATE_SUSPENDED|RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES,
+		nil,
+		nil,
+		HANDLE(0),
+		pi,
+	)
+
+	switch ret {
+	case RTL_CLONE_PARENT:
+		pid = pi.ClientId.UniqueProcess
+		ht, err := OpenThread(THREAD_ALL_ACCESS, false, pi.ClientId.UniqueThread)
+		if err != nil {
+			e = fmt.Errorf("OpenThread: %s", err)
+		}
+		err = ResumeThread(ht)
+		if err != nil {
+			e = fmt.Errorf("ResumeThread: %s", err)
+		}
+		CloseHandle(ht)
+	case RTL_CLONE_CHILD:
+		pid = 0
+		err := AllocConsole()
+		if err != nil {
+			e = fmt.Errorf("AllocConsole: %s", err)
+		}
+	default:
+		e = fmt.Errorf("0x%x", ret)
+	}
+	return
+}
diff --git a/packages/w32/fork_constants.go b/packages/w32/fork_constants.go
new file mode 100644
index 00000000..3e9b217c
--- /dev/null
+++ b/packages/w32/fork_constants.go
@@ -0,0 +1,26 @@
+package w32
+
+const (
+	RTL_CLONE_PROCESS_FLAGS_CREATE_SUSPENDED = 0x00000001
+	RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES  = 0x00000002
+	RTL_CLONE_PROCESS_FLAGS_NO_SYNCHRONIZE   = 0x00000004
+
+	RTL_CLONE_PARENT = 0
+	RTL_CLONE_CHILD  = 297
+
+	THREAD_TERMINATE                 = 0x0001
+	THREAD_SUSPEND_RESUME            = 0x0002
+	THREAD_GET_CONTEXT               = 0x0008
+	THREAD_SET_CONTEXT               = 0x0010
+	THREAD_SET_INFORMATION           = 0x0020
+	THREAD_QUERY_INFORMATION         = 0x0040
+	THREAD_SET_THREAD_TOKEN          = 0x0080
+	THREAD_IMPERSONATE               = 0x0100
+	THREAD_DIRECT_IMPERSONATION      = 0x0200
+	THREAD_SET_LIMITED_INFORMATION   = 0x0400
+	THREAD_QUERY_LIMITED_INFORMATION = 0x0800
+	THREAD_ALL_ACCESS                = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xffff
+
+	PROCESS_SET_SESSIONID = 0x0004
+	PROCESS_ALL_ACCESS    = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xffff
+)
diff --git a/packages/w32/fork_typedef.go b/packages/w32/fork_typedef.go
new file mode 100644
index 00000000..fcb90497
--- /dev/null
+++ b/packages/w32/fork_typedef.go
@@ -0,0 +1,89 @@
+package w32
+
+// combase!_SECTION_IMAGE_INFORMATION
+//    +0x000 TransferAddress  : Ptr64 Void
+//    +0x008 ZeroBits         : Uint4B
+//    +0x010 MaximumStackSize : Uint8B
+//    +0x018 CommittedStackSize : Uint8B
+//    +0x020 SubSystemType    : Uint4B
+//    +0x024 SubSystemMinorVersion : Uint2B
+//    +0x026 SubSystemMajorVersion : Uint2B
+//    +0x024 SubSystemVersion : Uint4B
+//    +0x028 MajorOperatingSystemVersion : Uint2B
+//    +0x02a MinorOperatingSystemVersion : Uint2B
+//    +0x028 OperatingSystemVersion : Uint4B
+//    +0x02c ImageCharacteristics : Uint2B
+//    +0x02e DllCharacteristics : Uint2B
+//    +0x030 Machine          : Uint2B
+//    +0x032 ImageContainsCode : UChar
+//    +0x033 ImageFlags       : UChar
+//    +0x033 ComPlusNativeReady : Pos 0, 1 Bit
+//    +0x033 ComPlusILOnly    : Pos 1, 1 Bit
+//    +0x033 ImageDynamicallyRelocated : Pos 2, 1 Bit
+//    +0x033 ImageMappedFlat  : Pos 3, 1 Bit
+//    +0x033 BaseBelow4gb     : Pos 4, 1 Bit
+//    +0x033 ComPlusPrefer32bit : Pos 5, 1 Bit
+//    +0x033 Reserved         : Pos 6, 2 Bits
+//    +0x034 LoaderFlags      : Uint4B
+//    +0x038 ImageFileSize    : Uint4B
+//    +0x03c CheckSum         : Uint4B
+type SECTION_IMAGE_INFORMATION struct {
+	TransferAddress             uintptr
+	ZeroBits                    uint32
+	MaximumStackSize            uint64
+	CommittedStackSize          uint64
+	SubSystemType               uint32
+	SubSystemMinorVersion       uint16
+	SubSystemMajorVersion       uint16
+	SubSystemVersion            uint32
+	MajorOperatingSystemVersion uint16
+	MinorOperatingSystemVersion uint16
+	OperatingSystemVersion      uint32
+	ImageCharacteristics        uint16
+	DllCharacteristics          uint16
+	Machine                     uint16
+	ImageContainsCode           uint8
+	ImageFlags                  uint8
+	ComPlusFlags                uint8
+	LoaderFlags                 uint32
+	ImageFileSize               uint32
+	CheckSum                    uint32
+}
+
+func (si *SECTION_IMAGE_INFORMATION) ComPlusNativeReady() bool {
+	return (si.ComPlusFlags & (1 << 0)) == 1
+}
+
+func (si *SECTION_IMAGE_INFORMATION) ComPlusILOnly() bool {
+	return (si.ComPlusFlags & (1 << 1)) == 1
+}
+
+func (si *SECTION_IMAGE_INFORMATION) ImageDynamicallyRelocated() bool {
+	return (si.ComPlusFlags & (1 << 2)) == 1
+}
+
+func (si *SECTION_IMAGE_INFORMATION) ImageMappedFlat() bool {
+	return (si.ComPlusFlags & (1 << 3)) == 1
+}
+
+func (si *SECTION_IMAGE_INFORMATION) BaseBelow4gb() bool {
+	return (si.ComPlusFlags & (1 << 4)) == 1
+}
+
+func (si *SECTION_IMAGE_INFORMATION) ComPlusPrefer32bit() bool {
+	return (si.ComPlusFlags & (1 << 5)) == 1
+}
+
+// combase!_RTL_USER_PROCESS_INFORMATION
+//    +0x000 Length           : Uint4B
+//    +0x008 Process          : Ptr64 Void
+//    +0x010 Thread           : Ptr64 Void
+//    +0x018 ClientId         : _CLIENT_ID
+//    +0x028 ImageInformation : _SECTION_IMAGE_INFORMATION
+type RTL_USER_PROCESS_INFORMATION struct {
+	Length           uint32
+	Process          HANDLE
+	Thread           HANDLE
+	ClientId         CLIENT_ID
+	ImageInformation SECTION_IMAGE_INFORMATION
+}
diff --git a/packages/w32/gdi32.go b/packages/w32/gdi32.go
new file mode 100644
index 00000000..39a81d6b
--- /dev/null
+++ b/packages/w32/gdi32.go
@@ -0,0 +1,543 @@
+// Copyright 2010-2012 The W32 Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package w32
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+var (
+	modgdi32 = syscall.NewLazyDLL("gdi32.dll")
+
+	procGetDeviceCaps             = modgdi32.NewProc("GetDeviceCaps")
+	procGetCurrentObject          = modgdi32.NewProc("GetCurrentObject")
+	procDeleteObject              = modgdi32.NewProc("DeleteObject")
+	procCreateFontIndirect        = modgdi32.NewProc("CreateFontIndirectW")
+	procAbortDoc                  = modgdi32.NewProc("AbortDoc")
+	procBitBlt                    = modgdi32.NewProc("BitBlt")
+	procPatBlt                    = modgdi32.NewProc("PatBlt")
+	procCloseEnhMetaFile          = modgdi32.NewProc("CloseEnhMetaFile")
+	procCopyEnhMetaFile           = modgdi32.NewProc("CopyEnhMetaFileW")
+	procCreateBrushIndirect       = modgdi32.NewProc("CreateBrushIndirect")
+	procCreateCompatibleDC        = modgdi32.NewProc("CreateCompatibleDC")
+	procCreateDC                  = modgdi32.NewProc("CreateDCW")
+	procCreateCompatibleBitmap    = modgdi32.NewProc("CreateCompatibleBitmap")
+	procCreateDIBSection          = modgdi32.NewProc("CreateDIBSection")
+	procCreateEnhMetaFile         = modgdi32.NewProc("CreateEnhMetaFileW")
+	procCreateIC                  = modgdi32.NewProc("CreateICW")
+	procDeleteDC                  = modgdi32.NewProc("DeleteDC")
+	procDeleteEnhMetaFile         = modgdi32.NewProc("DeleteEnhMetaFile")
+	procEllipse                   = modgdi32.NewProc("Ellipse")
+	procEndDoc                    = modgdi32.NewProc("EndDoc")
+	procEndPage                   = modgdi32.NewProc("EndPage")
+	procExtCreatePen              = modgdi32.NewProc("ExtCreatePen")
+	procGetEnhMetaFile            = modgdi32.NewProc("GetEnhMetaFileW")
+	procGetEnhMetaFileHeader      = modgdi32.NewProc("GetEnhMetaFileHeader")
+	procGetObject                 = modgdi32.NewProc("GetObjectW")
+	procGetStockObject            = modgdi32.NewProc("GetStockObject")
+	procGetTextExtentExPoint      = modgdi32.NewProc("GetTextExtentExPointW")
+	procGetTextExtentPoint32      = modgdi32.NewProc("GetTextExtentPoint32W")
+	procGetTextMetrics            = modgdi32.NewProc("GetTextMetricsW")
+	procLineTo                    = modgdi32.NewProc("LineTo")
+	procMoveToEx                  = modgdi32.NewProc("MoveToEx")
+	procPlayEnhMetaFile           = modgdi32.NewProc("PlayEnhMetaFile")
+	procRectangle                 = modgdi32.NewProc("Rectangle")
+	procResetDC                   = modgdi32.NewProc("ResetDCW")
+	procSelectObject              = modgdi32.NewProc("SelectObject")
+	procSetBkMode                 = modgdi32.NewProc("SetBkMode")
+	procSetBrushOrgEx             = modgdi32.NewProc("SetBrushOrgEx")
+	procSetStretchBltMode         = modgdi32.NewProc("SetStretchBltMode")
+	procSetTextColor              = modgdi32.NewProc("SetTextColor")
+	procSetBkColor                = modgdi32.NewProc("SetBkColor")
+	procStartDoc                  = modgdi32.NewProc("StartDocW")
+	procStartPage                 = modgdi32.NewProc("StartPage")
+	procStretchBlt                = modgdi32.NewProc("StretchBlt")
+	procSetDIBitsToDevice         = modgdi32.NewProc("SetDIBitsToDevice")
+	procChoosePixelFormat         = modgdi32.NewProc("ChoosePixelFormat")
+	procDescribePixelFormat       = modgdi32.NewProc("DescribePixelFormat")
+	procGetEnhMetaFilePixelFormat = modgdi32.NewProc("GetEnhMetaFilePixelFormat")
+	procGetPixelFormat            = modgdi32.NewProc("GetPixelFormat")
+	procSetPixelFormat            = modgdi32.NewProc("SetPixelFormat")
+	procSwapBuffers               = modgdi32.NewProc("SwapBuffers")
+)
+
+func GetDeviceCaps(hdc HDC, index int) int {
+	ret, _, _ := procGetDeviceCaps.Call(
+		uintptr(hdc),
+		uintptr(index))
+
+	return int(ret)
+}
+
+func GetCurrentObject(hdc HDC, uObjectType uint32) HGDIOBJ {
+	ret, _, _ := procGetCurrentObject.Call(
+		uintptr(hdc),
+		uintptr(uObjectType))
+
+	return HGDIOBJ(ret)
+}
+
+func DeleteObject(hObject HGDIOBJ) bool {
+	ret, _, _ := procDeleteObject.Call(
+		uintptr(hObject))
+
+	return ret != 0
+}
+
+func CreateFontIndirect(logFont *LOGFONT) HFONT {
+	ret, _, _ := procCreateFontIndirect.Call(
+		uintptr(unsafe.Pointer(logFont)))
+
+	return HFONT(ret)
+}
+
+func AbortDoc(hdc HDC) int {
+	ret, _, _ := procAbortDoc.Call(
+		uintptr(hdc))
+
+	return int(ret)
+}
+
+func BitBlt(hdcDest HDC, nXDest, nYDest, nWidth, nHeight int, hdcSrc HDC, nXSrc, nYSrc int, dwRop uint) {
+	ret, _, _ := procBitBlt.Call(
+		uintptr(hdcDest),
+		uintptr(nXDest),
+		uintptr(nYDest),
+		uintptr(nWidth),
+		uintptr(nHeight),
+		uintptr(hdcSrc),
+		uintptr(nXSrc),
+		uintptr(nYSrc),
+		uintptr(dwRop))
+
+	if ret == 0 {
+		panic("BitBlt failed")
+	}
+}
+
+func PatBlt(hdc HDC, nXLeft, nYLeft, nWidth, nHeight int, dwRop uint) {
+	ret, _, _ := procPatBlt.Call(
+		uintptr(hdc),
+		uintptr(nXLeft),
+		uintptr(nYLeft),
+		uintptr(nWidth),
+		uintptr(nHeight),
+		uintptr(dwRop))
+
+	if ret == 0 {
+		panic("PatBlt failed")
+	}
+}
+
+func CloseEnhMetaFile(hdc HDC) HENHMETAFILE {
+	ret, _, _ := procCloseEnhMetaFile.Call(
+		uintptr(hdc))
+
+	return HENHMETAFILE(ret)
+}
+
+func CopyEnhMetaFile(hemfSrc HENHMETAFILE, lpszFile *uint16) HENHMETAFILE {
+	ret, _, _ := procCopyEnhMetaFile.Call(
+		uintptr(hemfSrc),
+		uintptr(unsafe.Pointer(lpszFile)))
+
+	return HENHMETAFILE(ret)
+}
+
+func CreateBrushIndirect(lplb *LOGBRUSH) HBRUSH {
+	ret, _, _ := procCreateBrushIndirect.Call(
+		uintptr(unsafe.Pointer(lplb)))
+
+	return HBRUSH(ret)
+}
+
+func CreateCompatibleDC(hdc HDC) HDC {
+	ret, _, _ := procCreateCompatibleDC.Call(
+		uintptr(hdc))
+
+	if ret == 0 {
+		panic("Create compatible DC failed")
+	}
+
+	return HDC(ret)
+}
+
+func CreateDC(lpszDriver, lpszDevice, lpszOutput *uint16, lpInitData *DEVMODE) HDC {
+	ret, _, _ := procCreateDC.Call(
+		uintptr(unsafe.Pointer(lpszDriver)),
+		uintptr(unsafe.Pointer(lpszDevice)),
+		uintptr(unsafe.Pointer(lpszOutput)),
+		uintptr(unsafe.Pointer(lpInitData)))
+
+	return HDC(ret)
+}
+
+func CreateCompatibleBitmap(hdc HDC, width, height uint) HBITMAP {
+	ret, _, _ := procCreateCompatibleBitmap.Call(
+		uintptr(hdc),
+		uintptr(width),
+		uintptr(height))
+
+	return HBITMAP(ret)
+}
+
+func CreateDIBSection(hdc HDC, pbmi *BITMAPINFO, iUsage uint, ppvBits *unsafe.Pointer, hSection HANDLE, dwOffset uint) HBITMAP {
+	ret, _, _ := procCreateDIBSection.Call(
+		uintptr(hdc),
+		uintptr(unsafe.Pointer(pbmi)),
+		uintptr(iUsage),
+		uintptr(unsafe.Pointer(ppvBits)),
+		uintptr(hSection),
+		uintptr(dwOffset))
+
+	return HBITMAP(ret)
+}
+
+func CreateEnhMetaFile(hdcRef HDC, lpFilename *uint16, lpRect *RECT, lpDescription *uint16) HDC {
+	ret, _, _ := procCreateEnhMetaFile.Call(
+		uintptr(hdcRef),
+		uintptr(unsafe.Pointer(lpFilename)),
+		uintptr(unsafe.Pointer(lpRect)),
+		uintptr(unsafe.Pointer(lpDescription)))
+
+	return HDC(ret)
+}
+
+func CreateIC(lpszDriver, lpszDevice, lpszOutput *uint16, lpdvmInit *DEVMODE) HDC {
+	ret, _, _ := procCreateIC.Call(
+		uintptr(unsafe.Pointer(lpszDriver)),
+		uintptr(unsafe.Pointer(lpszDevice)),
+		uintptr(unsafe.Pointer(lpszOutput)),
+		uintptr(unsafe.Pointer(lpdvmInit)))
+
+	return HDC(ret)
+}
+
+func DeleteDC(hdc HDC) bool {
+	ret, _, _ := procDeleteDC.Call(
+		uintptr(hdc))
+
+	return ret != 0
+}
+
+func DeleteEnhMetaFile(hemf HENHMETAFILE) bool {
+	ret, _, _ := procDeleteEnhMetaFile.Call(
+		uintptr(hemf))
+
+	return ret != 0
+}
+
+func Ellipse(hdc HDC, nLeftRect, nTopRect, nRightRect, nBottomRect int) bool {
+	ret, _, _ := procEllipse.Call(
+		uintptr(hdc),
+		uintptr(nLeftRect),
+		uintptr(nTopRect),
+		uintptr(nRightRect),
+		uintptr(nBottomRect))
+
+	return ret != 0
+}
+
+func EndDoc(hdc HDC) int {
+	ret, _, _ := procEndDoc.Call(
+		uintptr(hdc))
+
+	return int(ret)
+}
+
+func EndPage(hdc HDC) int {
+	ret, _, _ := procEndPage.Call(
+		uintptr(hdc))
+
+	return int(ret)
+}
+
+func ExtCreatePen(dwPenStyle, dwWidth uint, lplb *LOGBRUSH, dwStyleCount uint, lpStyle *uint) HPEN {
+	ret, _, _ := procExtCreatePen.Call(
+		uintptr(dwPenStyle),
+		uintptr(dwWidth),
+		uintptr(unsafe.Pointer(lplb)),
+		uintptr(dwStyleCount),
+		uintptr(unsafe.Pointer(lpStyle)))
+
+	return HPEN(ret)
+}
+
+func GetEnhMetaFile(lpszMetaFile *uint16) HENHMETAFILE {
+	ret, _, _ := procGetEnhMetaFile.Call(
+		uintptr(unsafe.Pointer(lpszMetaFile)))
+
+	return HENHMETAFILE(ret)
+}
+
+func GetEnhMetaFileHeader(hemf HENHMETAFILE, cbBuffer uint, lpemh *ENHMETAHEADER) uint {
+	ret, _, _ := procGetEnhMetaFileHeader.Call(
+		uintptr(hemf),
+		uintptr(cbBuffer),
+		uintptr(unsafe.Pointer(lpemh)))
+
+	return uint(ret)
+}
+
+func GetObject(hgdiobj HGDIOBJ, cbBuffer uintptr, lpvObject unsafe.Pointer) int {
+	ret, _, _ := procGetObject.Call(
+		uintptr(hgdiobj),
+		uintptr(cbBuffer),
+		uintptr(lpvObject))
+
+	return int(ret)
+}
+
+func GetStockObject(fnObject int) HGDIOBJ {
+	ret, _, _ := procGetStockObject.Call(
+		uintptr(fnObject))
+
+	return HGDIOBJ(ret)
+}
+
+func GetTextExtentExPoint(hdc HDC, lpszStr *uint16, cchString, nMaxExtent int, lpnFit, alpDx *int, lpSize *SIZE) bool {
+	ret, _, _ := procGetTextExtentExPoint.Call(
+		uintptr(hdc),
+		uintptr(unsafe.Pointer(lpszStr)),
+		uintptr(cchString),
+		uintptr(nMaxExtent),
+		uintptr(unsafe.Pointer(lpnFit)),
+		uintptr(unsafe.Pointer(alpDx)),
+		uintptr(unsafe.Pointer(lpSize)))
+
+	return ret != 0
+}
+
+func GetTextExtentPoint32(hdc HDC, lpString *uint16, c int, lpSize *SIZE) bool {
+	ret, _, _ := procGetTextExtentPoint32.Call(
+		uintptr(hdc),
+		uintptr(unsafe.Pointer(lpString)),
+		uintptr(c),
+		uintptr(unsafe.Pointer(lpSize)))
+
+	return ret != 0
+}
+
+func GetTextMetrics(hdc HDC, lptm *TEXTMETRIC) bool {
+	ret, _, _ := procGetTextMetrics.Call(
+		uintptr(hdc),
+		uintptr(unsafe.Pointer(lptm)))
+
+	return ret != 0
+}
+
+func LineTo(hdc HDC, nXEnd, nYEnd int) bool {
+	ret, _, _ := procLineTo.Call(
+		uintptr(hdc),
+		uintptr(nXEnd),
+		uintptr(nYEnd))
+
+	return ret != 0
+}
+
+func MoveToEx(hdc HDC, x, y int, lpPoint *POINT) bool {
+	ret, _, _ := procMoveToEx.Call(
+		uintptr(hdc),
+		uintptr(x),
+		uintptr(y),
+		uintptr(unsafe.Pointer(lpPoint)))
+
+	return ret != 0
+}
+
+func PlayEnhMetaFile(hdc HDC, hemf HENHMETAFILE, lpRect *RECT) bool {
+	ret, _, _ := procPlayEnhMetaFile.Call(
+		uintptr(hdc),
+		uintptr(hemf),
+		uintptr(unsafe.Pointer(lpRect)))
+
+	return ret != 0
+}
+
+func Rectangle(hdc HDC, nLeftRect, nTopRect, nRightRect, nBottomRect int) bool {
+	ret, _, _ := procRectangle.Call(
+		uintptr(hdc),
+		uintptr(nLeftRect),
+		uintptr(nTopRect),
+		uintptr(nRightRect),
+		uintptr(nBottomRect))
+
+	return ret != 0
+}
+
+func ResetDC(hdc HDC, lpInitData *DEVMODE) HDC {
+	ret, _, _ := procResetDC.Call(
+		uintptr(hdc),
+		uintptr(unsafe.Pointer(lpInitData)))
+
+	return HDC(ret)
+}
+
+func SelectObject(hdc HDC, hgdiobj HGDIOBJ) HGDIOBJ {
+	ret, _, _ := procSelectObject.Call(
+		uintptr(hdc),
+		uintptr(hgdiobj))
+
+	if ret == 0 {
+		panic("SelectObject failed")
+	}
+
+	return HGDIOBJ(ret)
+}
+
+func SetBkMode(hdc HDC, iBkMode int) int {
+	ret, _, _ := procSetBkMode.Call(
+		uintptr(hdc),
+		uintptr(iBkMode))
+
+	if ret == 0 {
+		panic("SetBkMode failed")
+	}
+
+	return int(ret)
+}
+
+func SetBrushOrgEx(hdc HDC, nXOrg, nYOrg int, lppt *POINT) bool {
+	ret, _, _ := procSetBrushOrgEx.Call(
+		uintptr(hdc),
+		uintptr(nXOrg),
+		uintptr(nYOrg),
+		uintptr(unsafe.Pointer(lppt)))
+
+	return ret != 0
+}
+
+func SetStretchBltMode(hdc HDC, iStretchMode int) int {
+	ret, _, _ := procSetStretchBltMode.Call(
+		uintptr(hdc),
+		uintptr(iStretchMode))
+
+	return int(ret)
+}
+
+func SetTextColor(hdc HDC, crColor COLORREF) COLORREF {
+	ret, _, _ := procSetTextColor.Call(
+		uintptr(hdc),
+		uintptr(crColor))
+
+	if ret == CLR_INVALID {
+		panic("SetTextColor failed")
+	}
+
+	return COLORREF(ret)
+}
+
+func SetBkColor(hdc HDC, crColor COLORREF) COLORREF {
+	ret, _, _ := procSetBkColor.Call(
+		uintptr(hdc),
+		uintptr(crColor))
+
+	if ret == CLR_INVALID {
+		panic("SetBkColor failed")
+	}
+
+	return COLORREF(ret)
+}
+
+func StartDoc(hdc HDC, lpdi *DOCINFO) int {
+	ret, _, _ := procStartDoc.Call(
+		uintptr(hdc),
+		uintptr(unsafe.Pointer(lpdi)))
+
+	return int(ret)
+}
+
+func StartPage(hdc HDC) int {
+	ret, _, _ := procStartPage.Call(
+		uintptr(hdc))
+
+	return int(ret)
+}
+
+func StretchBlt(hdcDest HDC, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest int, hdcSrc HDC, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc int, dwRop uint) {
+	ret, _, _ := procStretchBlt.Call(
+		uintptr(hdcDest),
+		uintptr(nXOriginDest),
+		uintptr(nYOriginDest),
+		uintptr(nWidthDest),
+		uintptr(nHeightDest),
+		uintptr(hdcSrc),
+		uintptr(nXOriginSrc),
+		uintptr(nYOriginSrc),
+		uintptr(nWidthSrc),
+		uintptr(nHeightSrc),
+		uintptr(dwRop))
+
+	if ret == 0 {
+		panic("StretchBlt failed")
+	}
+}
+
+func SetDIBitsToDevice(hdc HDC, xDest, yDest, dwWidth, dwHeight, xSrc, ySrc int, uStartScan, cScanLines uint, lpvBits []byte, lpbmi *BITMAPINFO, fuColorUse uint) int {
+	ret, _, _ := procSetDIBitsToDevice.Call(
+		uintptr(hdc),
+		uintptr(xDest),
+		uintptr(yDest),
+		uintptr(dwWidth),
+		uintptr(dwHeight),
+		uintptr(xSrc),
+		uintptr(ySrc),
+		uintptr(uStartScan),
+		uintptr(cScanLines),
+		uintptr(unsafe.Pointer(&lpvBits[0])),
+		uintptr(unsafe.Pointer(lpbmi)),
+		uintptr(fuColorUse))
+
+	return int(ret)
+}
+
+func ChoosePixelFormat(hdc HDC, pfd *PIXELFORMATDESCRIPTOR) int {
+	ret, _, _ := procChoosePixelFormat.Call(
+		uintptr(hdc),
+		uintptr(unsafe.Pointer(pfd)),
+	)
+	return int(ret)
+}
+
+func DescribePixelFormat(hdc HDC, iPixelFormat int, nBytes uint, pfd *PIXELFORMATDESCRIPTOR) int {
+	ret, _, _ := procDescribePixelFormat.Call(
+		uintptr(hdc),
+		uintptr(iPixelFormat),
+		uintptr(nBytes),
+		uintptr(unsafe.Pointer(pfd)),
+	)
+	return int(ret)
+}
+
+func GetEnhMetaFilePixelFormat(hemf HENHMETAFILE, cbBuffer uint32, pfd *PIXELFORMATDESCRIPTOR) uint {
+	ret, _, _ := procGetEnhMetaFilePixelFormat.Call(
+		uintptr(hemf),
+		uintptr(cbBuffer),
+		uintptr(unsafe.Pointer(pfd)),
+	)
+	return uint(ret)
+}
+
+func GetPixelFormat(hdc HDC) int {
+	ret, _, _ := procGetPixelFormat.Call(
+		uintptr(hdc),
+	)
+	return int(ret)
+}
+
+func SetPixelFormat(hdc HDC, iPixelFormat int, pfd *PIXELFORMATDESCRIPTOR) bool {
+	ret, _, _ := procSetPixelFormat.Call(
+		uintptr(hdc),
+		uintptr(iPixelFormat),
+		uintptr(unsafe.Pointer(pfd)),
+	)
+	return ret == TRUE
+}
+
+func SwapBuffers(hdc HDC) bool {
+	ret, _, _ := procSwapBuffers.Call(uintptr(hdc))
+	return ret == TRUE
+}
diff --git a/packages/w32/gdiplus.go b/packages/w32/gdiplus.go
new file mode 100644
index 00000000..f3a8fca4
--- /dev/null
+++ b/packages/w32/gdiplus.go
@@ -0,0 +1,175 @@
+// Copyright 2010-2012 The W32 Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package w32
+
+import (
+	"errors"
+	"fmt"
+	"syscall"
+	"unsafe"
+)
+
+const (
+	Ok                        = 0
+	GenericError              = 1
+	InvalidParameter          = 2
+	OutOfMemory               = 3
+	ObjectBusy                = 4
+	InsufficientBuffer        = 5
+	NotImplemented            = 6
+	Win32Error                = 7
+	WrongState                = 8
+	Aborted                   = 9
+	FileNotFound              = 10
+	ValueOverflow             = 11
+	AccessDenied              = 12
+	UnknownImageFormat        = 13
+	FontFamilyNotFound        = 14
+	FontStyleNotFound         = 15
+	NotTrueTypeFont           = 16
+	UnsupportedGdiplusVersion = 17
+	GdiplusNotInitialized     = 18
+	PropertyNotFound          = 19
+	PropertyNotSupported      = 20
+	ProfileNotFound           = 21
+)
+
+func GetGpStatus(s int32) string {
+	switch s {
+	case Ok:
+		return "Ok"
+	case GenericError:
+		return "GenericError"
+	case InvalidParameter:
+		return "InvalidParameter"
+	case OutOfMemory:
+		return "OutOfMemory"
+	case ObjectBusy:
+		return "ObjectBusy"
+	case InsufficientBuffer:
+		return "InsufficientBuffer"
+	case NotImplemented:
+		return "NotImplemented"
+	case Win32Error:
+		return "Win32Error"
+	case WrongState:
+		return "WrongState"
+	case Aborted:
+		return "Aborted"
+	case FileNotFound:
+		return "FileNotFound"
+	case ValueOverflow:
+		return "ValueOverflow"
+	case AccessDenied:
+		return "AccessDenied"
+	case UnknownImageFormat:
+		return "UnknownImageFormat"
+	case FontFamilyNotFound:
+		return "FontFamilyNotFound"
+	case FontStyleNotFound:
+		return "FontStyleNotFound"
+	case NotTrueTypeFont:
+		return "NotTrueTypeFont"
+	case UnsupportedGdiplusVersion:
+		return "UnsupportedGdiplusVersion"
+	case GdiplusNotInitialized:
+		return "GdiplusNotInitialized"
+	case PropertyNotFound:
+		return "PropertyNotFound"
+	case PropertyNotSupported:
+		return "PropertyNotSupported"
+	case ProfileNotFound:
+		return "ProfileNotFound"
+	}
+	return "Unknown Status Value"
+}
+
+var (
+	token uintptr
+
+	modgdiplus = syscall.NewLazyDLL("gdiplus.dll")
+
+	procGdipCreateBitmapFromFile     = modgdiplus.NewProc("GdipCreateBitmapFromFile")
+	procGdipCreateBitmapFromHBITMAP  = modgdiplus.NewProc("GdipCreateBitmapFromHBITMAP")
+	procGdipCreateHBITMAPFromBitmap  = modgdiplus.NewProc("GdipCreateHBITMAPFromBitmap")
+	procGdipCreateBitmapFromResource = modgdiplus.NewProc("GdipCreateBitmapFromResource")
+	procGdipCreateBitmapFromStream   = modgdiplus.NewProc("GdipCreateBitmapFromStream")
+	procGdipDisposeImage             = modgdiplus.NewProc("GdipDisposeImage")
+	procGdiplusShutdown              = modgdiplus.NewProc("GdiplusShutdown")
+	procGdiplusStartup               = modgdiplus.NewProc("GdiplusStartup")
+)
+
+func GdipCreateBitmapFromFile(filename string) (*uintptr, error) {
+	var bitmap *uintptr
+	ret, _, _ := procGdipCreateBitmapFromFile.Call(
+		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(filename))),
+		uintptr(unsafe.Pointer(&bitmap)))
+
+	if ret != Ok {
+		return nil, errors.New(fmt.Sprintf("GdipCreateBitmapFromFile failed with status '%s' for file '%s'", GetGpStatus(int32(ret)), filename))
+	}
+
+	return bitmap, nil
+}
+
+func GdipCreateBitmapFromResource(instance HINSTANCE, resId *uint16) (*uintptr, error) {
+	var bitmap *uintptr
+	ret, _, _ := procGdipCreateBitmapFromResource.Call(
+		uintptr(instance),
+		uintptr(unsafe.Pointer(resId)),
+		uintptr(unsafe.Pointer(&bitmap)))
+
+	if ret != Ok {
+		return nil, errors.New(fmt.Sprintf("GdiCreateBitmapFromResource failed with status '%s'", GetGpStatus(int32(ret))))
+	}
+
+	return bitmap, nil
+}
+
+func GdipCreateBitmapFromStream(stream *IStream) (*uintptr, error) {
+	var bitmap *uintptr
+	ret, _, _ := procGdipCreateBitmapFromStream.Call(
+		uintptr(unsafe.Pointer(stream)),
+		uintptr(unsafe.Pointer(&bitmap)))
+
+	if ret != Ok {
+		return nil, errors.New(fmt.Sprintf("GdipCreateBitmapFromStream failed with status '%s'", GetGpStatus(int32(ret))))
+	}
+
+	return bitmap, nil
+}
+
+func GdipCreateHBITMAPFromBitmap(bitmap *uintptr, background uint32) (HBITMAP, error) {
+	var hbitmap HBITMAP
+	ret, _, _ := procGdipCreateHBITMAPFromBitmap.Call(
+		uintptr(unsafe.Pointer(bitmap)),
+		uintptr(unsafe.Pointer(&hbitmap)),
+		uintptr(background))
+
+	if ret != Ok {
+		return 0, errors.New(fmt.Sprintf("GdipCreateHBITMAPFromBitmap failed with status '%s'", GetGpStatus(int32(ret))))
+	}
+
+	return hbitmap, nil
+}
+
+func GdipDisposeImage(image *uintptr) {
+	procGdipDisposeImage.Call(uintptr(unsafe.Pointer(image)))
+}
+
+func GdiplusShutdown() {
+	procGdiplusShutdown.Call(token)
+}
+
+func GdiplusStartup(input *GdiplusStartupInput, output *GdiplusStartupOutput) {
+	ret, _, _ := procGdiplusStartup.Call(
+		uintptr(unsafe.Pointer(&token)),
+		uintptr(unsafe.Pointer(input)),
+		uintptr(unsafe.Pointer(output)))
+
+	if ret != Ok {
+		panic("GdiplusStartup failed with status " + GetGpStatus(int32(ret)))
+	}
+}
diff --git a/packages/w32/go.mod b/packages/w32/go.mod
new file mode 100644
index 00000000..ce6ffdfc
--- /dev/null
+++ b/packages/w32/go.mod
@@ -0,0 +1 @@
+module github.com/AllenDang/w32
diff --git a/packages/w32/idispatch.go b/packages/w32/idispatch.go
new file mode 100644
index 00000000..41634a64
--- /dev/null
+++ b/packages/w32/idispatch.go
@@ -0,0 +1,43 @@
+// Copyright 2010-2012 The W32 Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package w32
+
+import (
+	"unsafe"
+)
+
+type pIDispatchVtbl struct {
+	pQueryInterface   uintptr
+	pAddRef           uintptr
+	pRelease          uintptr
+	pGetTypeInfoCount uintptr
+	pGetTypeInfo      uintptr
+	pGetIDsOfNames    uintptr
+	pInvoke           uintptr
+}
+
+type IDispatch struct {
+	lpVtbl *pIDispatchVtbl
+}
+
+func (this *IDispatch) QueryInterface(id *GUID) *IDispatch {
+	return ComQueryInterface((*IUnknown)(unsafe.Pointer(this)), id)
+}
+
+func (this *IDispatch) AddRef() int32 {
+	return ComAddRef((*IUnknown)(unsafe.Pointer(this)))
+}
+
+func (this *IDispatch) Release() int32 {
+	return ComRelease((*IUnknown)(unsafe.Pointer(this)))
+}
+
+func (this *IDispatch) GetIDsOfName(names []string) []int32 {
+	return ComGetIDsOfName(this, names)
+}
+
+func (this *IDispatch) Invoke(dispid int32, dispatch int16, params ...interface{}) *VARIANT {
+	return ComInvoke(this, dispid, dispatch, params...)
+}
diff --git a/packages/w32/istream.go b/packages/w32/istream.go
new file mode 100644
index 00000000..2b840c3b
--- /dev/null
+++ b/packages/w32/istream.go
@@ -0,0 +1,31 @@
+// Copyright 2010-2012 The W32 Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package w32
+
+import (
+	"unsafe"
+)
+
+type pIStreamVtbl struct {
+	pQueryInterface uintptr
+	pAddRef         uintptr
+	pRelease        uintptr
+}
+
+type IStream struct {
+	lpVtbl *pIStreamVtbl
+}
+
+func (this *IStream) QueryInterface(id *GUID) *IDispatch {
+	return ComQueryInterface((*IUnknown)(unsafe.Pointer(this)), id)
+}
+
+func (this *IStream) AddRef() int32 {
+	return ComAddRef((*IUnknown)(unsafe.Pointer(this)))
+}
+
+func (this *IStream) Release() int32 {
+	return ComRelease((*IUnknown)(unsafe.Pointer(this)))
+}
diff --git a/packages/w32/iunknown.go b/packages/w32/iunknown.go
new file mode 100644
index 00000000..d63ff1bb
--- /dev/null
+++ b/packages/w32/iunknown.go
@@ -0,0 +1,27 @@
+// Copyright 2010-2012 The W32 Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package w32
+
+type pIUnknownVtbl struct {
+	pQueryInterface uintptr
+	pAddRef         uintptr
+	pRelease        uintptr
+}
+
+type IUnknown struct {
+	lpVtbl *pIUnknownVtbl
+}
+
+func (this *IUnknown) QueryInterface(id *GUID) *IDispatch {
+	return ComQueryInterface(this, id)
+}
+
+func (this *IUnknown) AddRef() int32 {
+	return ComAddRef(this)
+}
+
+func (this *IUnknown) Release() int32 {
+	return ComRelease(this)
+}
diff --git a/packages/w32/kernel32.go b/packages/w32/kernel32.go
new file mode 100644
index 00000000..28febbec
--- /dev/null
+++ b/packages/w32/kernel32.go
@@ -0,0 +1,388 @@
+// Copyright 2010-2012 The W32 Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package w32
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+var (
+	modkernel32 = syscall.NewLazyDLL("kernel32.dll")
+
+	procGetModuleHandle    = modkernel32.NewProc("GetModuleHandleW")
+	procMulDiv             = modkernel32.NewProc("MulDiv")
+	procGetConsoleWindow   = modkernel32.NewProc("GetConsoleWindow")
+	procGetCurrentThread   = modkernel32.NewProc("GetCurrentThread")
+	procGetLogicalDrives   = modkernel32.NewProc("GetLogicalDrives")
+	procGetUserDefaultLCID = modkernel32.NewProc("GetUserDefaultLCID")
+	procLstrlen            = modkernel32.NewProc("lstrlenW")
+	procLstrcpy            = modkernel32.NewProc("lstrcpyW")
+	procGlobalAlloc        = modkernel32.NewProc("GlobalAlloc")
+	procGlobalFree         = modkernel32.NewProc("GlobalFree")
+	procGlobalLock         = modkernel32.NewProc("GlobalLock")
+	procGlobalUnlock       = modkernel32.NewProc("GlobalUnlock")
+	procMoveMemory         = modkernel32.NewProc("RtlMoveMemory")
+	procFindResource       = modkernel32.NewProc("FindResourceW")
+	procSizeofResource     = modkernel32.NewProc("SizeofResource")
+	procLockResource       = modkernel32.NewProc("LockResource")
+	procLoadResource       = modkernel32.NewProc("LoadResource")
+	procGetLastError       = modkernel32.NewProc("GetLastError")
+	// procOpenProcess                = modkernel32.NewProc("OpenProcess")
+	// procTerminateProcess           = modkernel32.NewProc("TerminateProcess")
+	procCloseHandle                = modkernel32.NewProc("CloseHandle")
+	procCreateToolhelp32Snapshot   = modkernel32.NewProc("CreateToolhelp32Snapshot")
+	procModule32First              = modkernel32.NewProc("Module32FirstW")
+	procModule32Next               = modkernel32.NewProc("Module32NextW")
+	procGetSystemTimes             = modkernel32.NewProc("GetSystemTimes")
+	procGetConsoleScreenBufferInfo = modkernel32.NewProc("GetConsoleScreenBufferInfo")
+	procSetConsoleTextAttribute    = modkernel32.NewProc("SetConsoleTextAttribute")
+	procGetDiskFreeSpaceEx         = modkernel32.NewProc("GetDiskFreeSpaceExW")
+	procGetProcessTimes            = modkernel32.NewProc("GetProcessTimes")
+	procSetSystemTime              = modkernel32.NewProc("SetSystemTime")
+	procGetSystemTime              = modkernel32.NewProc("GetSystemTime")
+	procVirtualAllocEx             = modkernel32.NewProc("VirtualAllocEx")
+	procVirtualFreeEx              = modkernel32.NewProc("VirtualFreeEx")
+	procWriteProcessMemory         = modkernel32.NewProc("WriteProcessMemory")
+	procReadProcessMemory          = modkernel32.NewProc("ReadProcessMemory")
+	procQueryPerformanceCounter    = modkernel32.NewProc("QueryPerformanceCounter")
+	procQueryPerformanceFrequency  = modkernel32.NewProc("QueryPerformanceFrequency")
+)
+
+func GetModuleHandle(modulename string) HINSTANCE {
+	var mn uintptr
+	if modulename == "" {
+		mn = 0
+	} else {
+		mn = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(modulename)))
+	}
+	ret, _, _ := procGetModuleHandle.Call(mn)
+	return HINSTANCE(ret)
+}
+
+func MulDiv(number, numerator, denominator int) int {
+	ret, _, _ := procMulDiv.Call(
+		uintptr(number),
+		uintptr(numerator),
+		uintptr(denominator))
+
+	return int(ret)
+}
+
+func GetConsoleWindow() HWND {
+	ret, _, _ := procGetConsoleWindow.Call()
+
+	return HWND(ret)
+}
+
+func GetCurrentThread() HANDLE {
+	ret, _, _ := procGetCurrentThread.Call()
+
+	return HANDLE(ret)
+}
+
+func GetLogicalDrives() uint32 {
+	ret, _, _ := procGetLogicalDrives.Call()
+
+	return uint32(ret)
+}
+
+func GetUserDefaultLCID() uint32 {
+	ret, _, _ := procGetUserDefaultLCID.Call()
+
+	return uint32(ret)
+}
+
+func Lstrlen(lpString *uint16) int {
+	ret, _, _ := procLstrlen.Call(uintptr(unsafe.Pointer(lpString)))
+
+	return int(ret)
+}
+
+func Lstrcpy(buf []uint16, lpString *uint16) {
+	procLstrcpy.Call(
+		uintptr(unsafe.Pointer(&buf[0])),
+		uintptr(unsafe.Pointer(lpString)))
+}
+
+func GlobalAlloc(uFlags uint, dwBytes uint32) HGLOBAL {
+	ret, _, _ := procGlobalAlloc.Call(
+		uintptr(uFlags),
+		uintptr(dwBytes))
+
+	if ret == 0 {
+		panic("GlobalAlloc failed")
+	}
+
+	return HGLOBAL(ret)
+}
+
+func GlobalFree(hMem HGLOBAL) {
+	ret, _, _ := procGlobalFree.Call(uintptr(hMem))
+
+	if ret != 0 {
+		panic("GlobalFree failed")
+	}
+}
+
+func GlobalLock(hMem HGLOBAL) unsafe.Pointer {
+	ret, _, _ := procGlobalLock.Call(uintptr(hMem))
+
+	if ret == 0 {
+		panic("GlobalLock failed")
+	}
+
+	return unsafe.Pointer(ret)
+}
+
+func GlobalUnlock(hMem HGLOBAL) bool {
+	ret, _, _ := procGlobalUnlock.Call(uintptr(hMem))
+
+	return ret != 0
+}
+
+func MoveMemory(destination, source unsafe.Pointer, length uint32) {
+	procMoveMemory.Call(
+		uintptr(unsafe.Pointer(destination)),
+		uintptr(source),
+		uintptr(length))
+}
+
+func FindResource(hModule HMODULE, lpName, lpType *uint16) (HRSRC, error) {
+	ret, _, _ := procFindResource.Call(
+		uintptr(hModule),
+		uintptr(unsafe.Pointer(lpName)),
+		uintptr(unsafe.Pointer(lpType)))
+
+	if ret == 0 {
+		return 0, syscall.GetLastError()
+	}
+
+	return HRSRC(ret), nil
+}
+
+func SizeofResource(hModule HMODULE, hResInfo HRSRC) uint32 {
+	ret, _, _ := procSizeofResource.Call(
+		uintptr(hModule),
+		uintptr(hResInfo))
+
+	if ret == 0 {
+		panic("SizeofResource failed")
+	}
+
+	return uint32(ret)
+}
+
+func LockResource(hResData HGLOBAL) unsafe.Pointer {
+	ret, _, _ := procLockResource.Call(uintptr(hResData))
+
+	if ret == 0 {
+		panic("LockResource failed")
+	}
+
+	return unsafe.Pointer(ret)
+}
+
+func LoadResource(hModule HMODULE, hResInfo HRSRC) HGLOBAL {
+	ret, _, _ := procLoadResource.Call(
+		uintptr(hModule),
+		uintptr(hResInfo))
+
+	if ret == 0 {
+		panic("LoadResource failed")
+	}
+
+	return HGLOBAL(ret)
+}
+
+func GetLastError() uint32 {
+	ret, _, _ := procGetLastError.Call()
+	return uint32(ret)
+}
+
+// func OpenProcess(desiredAccess uint32, inheritHandle bool, processId uint32) HANDLE {
+// 	inherit := 0
+// 	if inheritHandle {
+// 		inherit = 1
+// 	}
+
+// 	ret, _, _ := procOpenProcess.Call(
+// 		uintptr(desiredAccess),
+// 		uintptr(inherit),
+// 		uintptr(processId))
+// 	return HANDLE(ret)
+// }
+
+// func TerminateProcess(hProcess HANDLE, uExitCode uint) bool {
+// 	ret, _, _ := procTerminateProcess.Call(
+// 		uintptr(hProcess),
+// 		uintptr(uExitCode))
+// 	return ret != 0
+// }
+
+func CloseHandle(object HANDLE) bool {
+	ret, _, _ := procCloseHandle.Call(
+		uintptr(object))
+	return ret != 0
+}
+
+func CreateToolhelp32Snapshot(flags, processId uint32) HANDLE {
+	ret, _, _ := procCreateToolhelp32Snapshot.Call(
+		uintptr(flags),
+		uintptr(processId))
+
+	if ret <= 0 {
+		return HANDLE(0)
+	}
+
+	return HANDLE(ret)
+}
+
+func Module32First(snapshot HANDLE, me *MODULEENTRY32) bool {
+	ret, _, _ := procModule32First.Call(
+		uintptr(snapshot),
+		uintptr(unsafe.Pointer(me)))
+
+	return ret != 0
+}
+
+func Module32Next(snapshot HANDLE, me *MODULEENTRY32) bool {
+	ret, _, _ := procModule32Next.Call(
+		uintptr(snapshot),
+		uintptr(unsafe.Pointer(me)))
+
+	return ret != 0
+}
+
+func GetSystemTimes(lpIdleTime, lpKernelTime, lpUserTime *FILETIME) bool {
+	ret, _, _ := procGetSystemTimes.Call(
+		uintptr(unsafe.Pointer(lpIdleTime)),
+		uintptr(unsafe.Pointer(lpKernelTime)),
+		uintptr(unsafe.Pointer(lpUserTime)))
+
+	return ret != 0
+}
+
+func GetProcessTimes(hProcess HANDLE, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime *FILETIME) bool {
+	ret, _, _ := procGetProcessTimes.Call(
+		uintptr(hProcess),
+		uintptr(unsafe.Pointer(lpCreationTime)),
+		uintptr(unsafe.Pointer(lpExitTime)),
+		uintptr(unsafe.Pointer(lpKernelTime)),
+		uintptr(unsafe.Pointer(lpUserTime)))
+
+	return ret != 0
+}
+
+func GetConsoleScreenBufferInfo(hConsoleOutput HANDLE) *CONSOLE_SCREEN_BUFFER_INFO {
+	var csbi CONSOLE_SCREEN_BUFFER_INFO
+	ret, _, _ := procGetConsoleScreenBufferInfo.Call(
+		uintptr(hConsoleOutput),
+		uintptr(unsafe.Pointer(&csbi)))
+	if ret == 0 {
+		return nil
+	}
+	return &csbi
+}
+
+func SetConsoleTextAttribute(hConsoleOutput HANDLE, wAttributes uint16) bool {
+	ret, _, _ := procSetConsoleTextAttribute.Call(
+		uintptr(hConsoleOutput),
+		uintptr(wAttributes))
+	return ret != 0
+}
+
+func GetDiskFreeSpaceEx(dirName string) (r bool,
+	freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes uint64) {
+	ret, _, _ := procGetDiskFreeSpaceEx.Call(
+		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(dirName))),
+		uintptr(unsafe.Pointer(&freeBytesAvailable)),
+		uintptr(unsafe.Pointer(&totalNumberOfBytes)),
+		uintptr(unsafe.Pointer(&totalNumberOfFreeBytes)))
+	return ret != 0,
+		freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes
+}
+
+func GetSystemTime() *SYSTEMTIME {
+	var time SYSTEMTIME
+	procGetSystemTime.Call(
+		uintptr(unsafe.Pointer(&time)))
+	return &time
+}
+
+func SetSystemTime(time *SYSTEMTIME) bool {
+	ret, _, _ := procSetSystemTime.Call(
+		uintptr(unsafe.Pointer(time)))
+	return ret != 0
+}
+
+func VirtualAllocEx(hProcess HANDLE, lpAddress, dwSize uintptr, flAllocationType, flProtect uint32) uintptr {
+	ret, _, _ := procVirtualAllocEx.Call(
+		uintptr(hProcess),
+		lpAddress,
+		dwSize,
+		uintptr(flAllocationType),
+		uintptr(flProtect),
+	)
+
+	return ret
+}
+
+func VirtualFreeEx(hProcess HANDLE, lpAddress, dwSize uintptr, dwFreeType uint32) bool {
+	ret, _, _ := procVirtualFreeEx.Call(
+		uintptr(hProcess),
+		lpAddress,
+		dwSize,
+		uintptr(dwFreeType),
+	)
+
+	return ret != 0
+}
+
+func WriteProcessMemory(hProcess HANDLE, lpBaseAddress, lpBuffer, nSize uintptr) (int, bool) {
+	var nBytesWritten int
+	ret, _, _ := procWriteProcessMemory.Call(
+		uintptr(hProcess),
+		lpBaseAddress,
+		lpBuffer,
+		nSize,
+		uintptr(unsafe.Pointer(&nBytesWritten)),
+	)
+
+	return nBytesWritten, ret != 0
+}
+
+func ReadProcessMemory(hProcess HANDLE, lpBaseAddress, nSize uintptr) (lpBuffer []uint16, lpNumberOfBytesRead int, ok bool) {
+
+	var nBytesRead int
+	buf := make([]uint16, nSize)
+	ret, _, _ := procReadProcessMemory.Call(
+		uintptr(hProcess),
+		lpBaseAddress,
+		uintptr(unsafe.Pointer(&buf[0])),
+		nSize,
+		uintptr(unsafe.Pointer(&nBytesRead)),
+	)
+
+	return buf, nBytesRead, ret != 0
+}
+
+func QueryPerformanceCounter() uint64 {
+	result := uint64(0)
+	procQueryPerformanceCounter.Call(
+		uintptr(unsafe.Pointer(&result)),
+	)
+
+	return result
+}
+
+func QueryPerformanceFrequency() uint64 {
+	result := uint64(0)
+	procQueryPerformanceFrequency.Call(
+		uintptr(unsafe.Pointer(&result)),
+	)
+
+	return result
+}
diff --git a/packages/w32/ole32.go b/packages/w32/ole32.go
new file mode 100644
index 00000000..a7f79b55
--- /dev/null
+++ b/packages/w32/ole32.go
@@ -0,0 +1,63 @@
+// Copyright 2010-2012 The W32 Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package w32
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+var (
+	modole32 = syscall.NewLazyDLL("ole32.dll")
+
+	procCoInitializeEx        = modole32.NewProc("CoInitializeEx")
+	procCoInitialize          = modole32.NewProc("CoInitialize")
+	procCoUninitialize        = modole32.NewProc("CoUninitialize")
+	procCreateStreamOnHGlobal = modole32.NewProc("CreateStreamOnHGlobal")
+)
+
+func CoInitializeEx(coInit uintptr) HRESULT {
+	ret, _, _ := procCoInitializeEx.Call(
+		0,
+		coInit)
+
+	switch uint32(ret) {
+	case E_INVALIDARG:
+		panic("CoInitializeEx failed with E_INVALIDARG")
+	case E_OUTOFMEMORY:
+		panic("CoInitializeEx failed with E_OUTOFMEMORY")
+	case E_UNEXPECTED:
+		panic("CoInitializeEx failed with E_UNEXPECTED")
+	}
+
+	return HRESULT(ret)
+}
+
+func CoInitialize() {
+	procCoInitialize.Call(0)
+}
+
+func CoUninitialize() {
+	procCoUninitialize.Call()
+}
+
+func CreateStreamOnHGlobal(hGlobal HGLOBAL, fDeleteOnRelease bool) *IStream {
+	stream := new(IStream)
+	ret, _, _ := procCreateStreamOnHGlobal.Call(
+		uintptr(hGlobal),
+		uintptr(BoolToBOOL(fDeleteOnRelease)),
+		uintptr(unsafe.Pointer(&stream)))
+
+	switch uint32(ret) {
+	case E_INVALIDARG:
+		panic("CreateStreamOnHGlobal failed with E_INVALIDARG")
+	case E_OUTOFMEMORY:
+		panic("CreateStreamOnHGlobal failed with E_OUTOFMEMORY")
+	case E_UNEXPECTED:
+		panic("CreateStreamOnHGlobal failed with E_UNEXPECTED")
+	}
+
+	return stream
+}
diff --git a/packages/w32/oleaut32.go b/packages/w32/oleaut32.go
new file mode 100644
index 00000000..0eeeab72
--- /dev/null
+++ b/packages/w32/oleaut32.go
@@ -0,0 +1,48 @@
+// Copyright 2010-2012 The W32 Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package w32
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+var (
+	modoleaut32 = syscall.NewLazyDLL("oleaut32")
+
+	procVariantInit        = modoleaut32.NewProc("VariantInit")
+	procSysAllocString     = modoleaut32.NewProc("SysAllocString")
+	procSysFreeString      = modoleaut32.NewProc("SysFreeString")
+	procSysStringLen       = modoleaut32.NewProc("SysStringLen")
+	procCreateDispTypeInfo = modoleaut32.NewProc("CreateDispTypeInfo")
+	procCreateStdDispatch  = modoleaut32.NewProc("CreateStdDispatch")
+)
+
+func VariantInit(v *VARIANT) {
+	hr, _, _ := procVariantInit.Call(uintptr(unsafe.Pointer(v)))
+	if hr != 0 {
+		panic("Invoke VariantInit error.")
+	}
+	return
+}
+
+func SysAllocString(v string) (ss *int16) {
+	pss, _, _ := procSysAllocString.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(v))))
+	ss = (*int16)(unsafe.Pointer(pss))
+	return
+}
+
+func SysFreeString(v *int16) {
+	hr, _, _ := procSysFreeString.Call(uintptr(unsafe.Pointer(v)))
+	if hr != 0 {
+		panic("Invoke SysFreeString error.")
+	}
+	return
+}
+
+func SysStringLen(v *int16) uint {
+	l, _, _ := procSysStringLen.Call(uintptr(unsafe.Pointer(v)))
+	return uint(l)
+}
diff --git a/packages/w32/opengl32.go b/packages/w32/opengl32.go
new file mode 100644
index 00000000..7363bb10
--- /dev/null
+++ b/packages/w32/opengl32.go
@@ -0,0 +1,72 @@
+// Copyright 2010-2012 The W32 Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package w32
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+var (
+	modopengl32 = syscall.NewLazyDLL("opengl32.dll")
+
+	procwglCreateContext      = modopengl32.NewProc("wglCreateContext")
+	procwglCreateLayerContext = modopengl32.NewProc("wglCreateLayerContext")
+	procwglDeleteContext      = modopengl32.NewProc("wglDeleteContext")
+	procwglGetProcAddress     = modopengl32.NewProc("wglGetProcAddress")
+	procwglMakeCurrent        = modopengl32.NewProc("wglMakeCurrent")
+	procwglShareLists         = modopengl32.NewProc("wglShareLists")
+)
+
+func WglCreateContext(hdc HDC) HGLRC {
+	ret, _, _ := procwglCreateContext.Call(
+		uintptr(hdc),
+	)
+
+	return HGLRC(ret)
+}
+
+func WglCreateLayerContext(hdc HDC, iLayerPlane int) HGLRC {
+	ret, _, _ := procwglCreateLayerContext.Call(
+		uintptr(hdc),
+		uintptr(iLayerPlane),
+	)
+
+	return HGLRC(ret)
+}
+
+func WglDeleteContext(hglrc HGLRC) bool {
+	ret, _, _ := procwglDeleteContext.Call(
+		uintptr(hglrc),
+	)
+
+	return ret == TRUE
+}
+
+func WglGetProcAddress(szProc string) uintptr {
+	ret, _, _ := procwglGetProcAddress.Call(
+		uintptr(unsafe.Pointer(syscall.StringBytePtr(szProc))),
+	)
+
+	return ret
+}
+
+func WglMakeCurrent(hdc HDC, hglrc HGLRC) bool {
+	ret, _, _ := procwglMakeCurrent.Call(
+		uintptr(hdc),
+		uintptr(hglrc),
+	)
+
+	return ret == TRUE
+}
+
+func WglShareLists(hglrc1, hglrc2 HGLRC) bool {
+	ret, _, _ := procwglShareLists.Call(
+		uintptr(hglrc1),
+		uintptr(hglrc2),
+	)
+
+	return ret == TRUE
+}
diff --git a/packages/w32/psapi.go b/packages/w32/psapi.go
new file mode 100644
index 00000000..bd1e1262
--- /dev/null
+++ b/packages/w32/psapi.go
@@ -0,0 +1,25 @@
+// Copyright 2010-2012 The W32 Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package w32
+
+import (
+	"syscall"
+	"unsafe"
+)
+
+var (
+	modpsapi = syscall.NewLazyDLL("psapi.dll")
+
+	procEnumProcesses = modpsapi.NewProc("EnumProcesses")
+)
+
+func EnumProcesses(processIds []uint32, cb uint32, bytesReturned *uint32) bool {
+	ret, _, _ := procEnumProcesses.Call(
+		uintptr(unsafe.Pointer(&processIds[0])),
+		uintptr(cb),
+		uintptr(unsafe.Pointer(bytesReturned)))
+
+	return ret != 0
+}
diff --git a/packages/w32/shell32.go b/packages/w32/shell32.go
new file mode 100644
index 00000000..0923b8b6
--- /dev/null
+++ b/packages/w32/shell32.go
@@ -0,0 +1,153 @@
+// Copyright 2010-2012 The W32 Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package w32
+
+import (
+	"errors"
+	"fmt"
+	"syscall"
+	"unsafe"
+)
+
+var (
+	modshell32 = syscall.NewLazyDLL("shell32.dll")
+
+	procSHBrowseForFolder   = modshell32.NewProc("SHBrowseForFolderW")
+	procSHGetPathFromIDList = modshell32.NewProc("SHGetPathFromIDListW")
+	procDragAcceptFiles     = modshell32.NewProc("DragAcceptFiles")
+	procDragQueryFile       = modshell32.NewProc("DragQueryFileW")
+	procDragQueryPoint      = modshell32.NewProc("DragQueryPoint")
+	procDragFinish          = modshell32.NewProc("DragFinish")
+	procShellExecute        = modshell32.NewProc("ShellExecuteW")
+	procExtractIcon         = modshell32.NewProc("ExtractIconW")
+)
+
+func SHBrowseForFolder(bi *BROWSEINFO) uintptr {
+	ret, _, _ := procSHBrowseForFolder.Call(uintptr(unsafe.Pointer(bi)))
+
+	return ret
+}
+
+func SHGetPathFromIDList(idl uintptr) string {
+	buf := make([]uint16, 1024)
+	procSHGetPathFromIDList.Call(
+		idl,
+		uintptr(unsafe.Pointer(&buf[0])))
+
+	return syscall.UTF16ToString(buf)
+}
+
+func DragAcceptFiles(hwnd HWND, accept bool) {
+	procDragAcceptFiles.Call(
+		uintptr(hwnd),
+		uintptr(BoolToBOOL(accept)))
+}
+
+func DragQueryFile(hDrop HDROP, iFile uint) (fileName string, fileCount uint) {
+	ret, _, _ := procDragQueryFile.Call(
+		uintptr(hDrop),
+		uintptr(iFile),
+		0,
+		0)
+
+	fileCount = uint(ret)
+
+	if iFile != 0xFFFFFFFF {
+		buf := make([]uint16, fileCount+1)
+
+		ret, _, _ := procDragQueryFile.Call(
+			uintptr(hDrop),
+			uintptr(iFile),
+			uintptr(unsafe.Pointer(&buf[0])),
+			uintptr(fileCount+1))
+
+		if ret == 0 {
+			panic("Invoke DragQueryFile error.")
+		}
+
+		fileName = syscall.UTF16ToString(buf)
+	}
+
+	return
+}
+
+func DragQueryPoint(hDrop HDROP) (x, y int, isClientArea bool) {
+	var pt POINT
+	ret, _, _ := procDragQueryPoint.Call(
+		uintptr(hDrop),
+		uintptr(unsafe.Pointer(&pt)))
+
+	return int(pt.X), int(pt.Y), (ret == 1)
+}
+
+func DragFinish(hDrop HDROP) {
+	procDragFinish.Call(uintptr(hDrop))
+}
+
+func ShellExecute(hwnd HWND, lpOperation, lpFile, lpParameters, lpDirectory string, nShowCmd int) error {
+	var op, param, directory uintptr
+	if len(lpOperation) != 0 {
+		op = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpOperation)))
+	}
+	if len(lpParameters) != 0 {
+		param = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpParameters)))
+	}
+	if len(lpDirectory) != 0 {
+		directory = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpDirectory)))
+	}
+
+	ret, _, _ := procShellExecute.Call(
+		uintptr(hwnd),
+		op,
+		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpFile))),
+		param,
+		directory,
+		uintptr(nShowCmd))
+
+	errorMsg := ""
+	if ret != 0 && ret <= 32 {
+		switch int(ret) {
+		case ERROR_FILE_NOT_FOUND:
+			errorMsg = "The specified file was not found."
+		case ERROR_PATH_NOT_FOUND:
+			errorMsg = "The specified path was not found."
+		case ERROR_BAD_FORMAT:
+			errorMsg = "The .exe file is invalid (non-Win32 .exe or error in .exe image)."
+		case SE_ERR_ACCESSDENIED:
+			errorMsg = "The operating system denied access to the specified file."
+		case SE_ERR_ASSOCINCOMPLETE:
+			errorMsg = "The file name association is incomplete or invalid."
+		case SE_ERR_DDEBUSY:
+			errorMsg = "The DDE transaction could not be completed because other DDE transactions were being processed."
+		case SE_ERR_DDEFAIL:
+			errorMsg = "The DDE transaction failed."
+		case SE_ERR_DDETIMEOUT:
+			errorMsg = "The DDE transaction could not be completed because the request timed out."
+		case SE_ERR_DLLNOTFOUND:
+			errorMsg = "The specified DLL was not found."
+		case SE_ERR_NOASSOC:
+			errorMsg = "There is no application associated with the given file name extension. This error will also be returned if you attempt to print a file that is not printable."
+		case SE_ERR_OOM:
+			errorMsg = "There was not enough memory to complete the operation."
+		case SE_ERR_SHARE:
+			errorMsg = "A sharing violation occurred."
+		default:
+			errorMsg = fmt.Sprintf("Unknown error occurred with error code %v", ret)
+		}
+	} else {
+		return nil
+	}
+
+	return errors.New(errorMsg)
+}
+
+func ExtractIcon(lpszExeFileName string, nIconIndex int) HICON {
+	ret, _, _ := procExtractIcon.Call(
+		0,
+		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpszExeFileName))),
+		uintptr(nIconIndex))
+
+	return HICON(ret)
+}
diff --git a/packages/w32/typedef.go b/packages/w32/typedef.go
new file mode 100644
index 00000000..118f76c6
--- /dev/null
+++ b/packages/w32/typedef.go
@@ -0,0 +1,891 @@
+// Copyright 2010-2012 The W32 Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package w32
+
+import (
+	"unsafe"
+)
+
+// From MSDN: Windows Data Types
+// http://msdn.microsoft.com/en-us/library/s3f49ktz.aspx
+// http://msdn.microsoft.com/en-us/library/windows/desktop/aa383751.aspx
+// ATOM                  WORD
+// BOOL                  int32
+// BOOLEAN               byte
+// BYTE                  byte
+// CCHAR                 int8
+// CHAR                  int8
+// COLORREF              DWORD
+// DWORD                 uint32
+// DWORDLONG             ULONGLONG
+// DWORD_PTR             ULONG_PTR
+// DWORD32               uint32
+// DWORD64               uint64
+// FLOAT                 float32
+// HACCEL                HANDLE
+// HALF_PTR              struct{} // ???
+// HANDLE                PVOID
+// HBITMAP               HANDLE
+// HBRUSH                HANDLE
+// HCOLORSPACE           HANDLE
+// HCONV                 HANDLE
+// HCONVLIST             HANDLE
+// HCURSOR               HANDLE
+// HDC                   HANDLE
+// HDDEDATA              HANDLE
+// HDESK                 HANDLE
+// HDROP                 HANDLE
+// HDWP                  HANDLE
+// HENHMETAFILE          HANDLE
+// HFILE                 HANDLE
+// HFONT                 HANDLE
+// HGDIOBJ               HANDLE
+// HGLOBAL               HANDLE
+// HHOOK                 HANDLE
+// HICON                 HANDLE
+// HINSTANCE             HANDLE
+// HKEY                  HANDLE
+// HKL                   HANDLE
+// HLOCAL                HANDLE
+// HMENU                 HANDLE
+// HMETAFILE             HANDLE
+// HMODULE               HANDLE
+// HPALETTE              HANDLE
+// HPEN                  HANDLE
+// HRESULT               int32
+// HRGN                  HANDLE
+// HSZ                   HANDLE
+// HWINSTA               HANDLE
+// HWND                  HANDLE
+// INT                   int32
+// INT_PTR               uintptr
+// INT8                  int8
+// INT16                 int16
+// INT32                 int32
+// INT64                 int64
+// LANGID                WORD
+// LCID                  DWORD
+// LCTYPE                DWORD
+// LGRPID                DWORD
+// LONG                  int32
+// LONGLONG              int64
+// LONG_PTR              uintptr
+// LONG32                int32
+// LONG64                int64
+// LPARAM                LONG_PTR
+// LPBOOL                *BOOL
+// LPBYTE                *BYTE
+// LPCOLORREF            *COLORREF
+// LPCSTR                *int8
+// LPCTSTR               LPCWSTR
+// LPCVOID               unsafe.Pointer
+// LPCWSTR               *WCHAR
+// LPDWORD               *DWORD
+// LPHANDLE              *HANDLE
+// LPINT                 *INT
+// LPLONG                *LONG
+// LPSTR                 *CHAR
+// LPTSTR                LPWSTR
+// LPVOID                unsafe.Pointer
+// LPWORD                *WORD
+// LPWSTR                *WCHAR
+// LRESULT               LONG_PTR
+// PBOOL                 *BOOL
+// PBOOLEAN              *BOOLEAN
+// PBYTE                 *BYTE
+// PCHAR                 *CHAR
+// PCSTR                 *CHAR
+// PCTSTR                PCWSTR
+// PCWSTR                *WCHAR
+// PDWORD                *DWORD
+// PDWORDLONG            *DWORDLONG
+// PDWORD_PTR            *DWORD_PTR
+// PDWORD32              *DWORD32
+// PDWORD64              *DWORD64
+// PFLOAT                *FLOAT
+// PHALF_PTR             *HALF_PTR
+// PHANDLE               *HANDLE
+// PHKEY                 *HKEY
+// PINT_PTR              *INT_PTR
+// PINT8                 *INT8
+// PINT16                *INT16
+// PINT32                *INT32
+// PINT64                *INT64
+// PLCID                 *LCID
+// PLONG                 *LONG
+// PLONGLONG             *LONGLONG
+// PLONG_PTR             *LONG_PTR
+// PLONG32               *LONG32
+// PLONG64               *LONG64
+// POINTER_32            struct{} // ???
+// POINTER_64            struct{} // ???
+// POINTER_SIGNED        uintptr
+// POINTER_UNSIGNED      uintptr
+// PSHORT                *SHORT
+// PSIZE_T               *SIZE_T
+// PSSIZE_T              *SSIZE_T
+// PSTR                  *CHAR
+// PTBYTE                *TBYTE
+// PTCHAR                *TCHAR
+// PTSTR                 PWSTR
+// PUCHAR                *UCHAR
+// PUHALF_PTR            *UHALF_PTR
+// PUINT                 *UINT
+// PUINT_PTR             *UINT_PTR
+// PUINT8                *UINT8
+// PUINT16               *UINT16
+// PUINT32               *UINT32
+// PUINT64               *UINT64
+// PULONG                *ULONG
+// PULONGLONG            *ULONGLONG
+// PULONG_PTR            *ULONG_PTR
+// PULONG32              *ULONG32
+// PULONG64              *ULONG64
+// PUSHORT               *USHORT
+// PVOID                 unsafe.Pointer
+// PWCHAR                *WCHAR
+// PWORD                 *WORD
+// PWSTR                 *WCHAR
+// QWORD                 uint64
+// SC_HANDLE             HANDLE
+// SC_LOCK               LPVOID
+// SERVICE_STATUS_HANDLE HANDLE
+// SHORT                 int16
+// SIZE_T                ULONG_PTR
+// SSIZE_T               LONG_PTR
+// TBYTE                 WCHAR
+// TCHAR                 WCHAR
+// UCHAR                 uint8
+// UHALF_PTR             struct{} // ???
+// UINT                  uint32
+// UINT_PTR              uintptr
+// UINT8                 uint8
+// UINT16                uint16
+// UINT32                uint32
+// UINT64                uint64
+// ULONG                 uint32
+// ULONGLONG             uint64
+// ULONG_PTR             uintptr
+// ULONG32               uint32
+// ULONG64               uint64
+// USHORT                uint16
+// USN                   LONGLONG
+// WCHAR                 uint16
+// WORD                  uint16
+// WPARAM                UINT_PTR
+type (
+	ATOM            uint16
+	BOOL            int32
+	COLORREF        uint32
+	DWM_FRAME_COUNT uint64
+	DWORD           uint32
+	HACCEL          HANDLE
+	HANDLE          uintptr
+	HBITMAP         HANDLE
+	HBRUSH          HANDLE
+	HCURSOR         HANDLE
+	HDC             HANDLE
+	HDROP           HANDLE
+	HDWP            HANDLE
+	HENHMETAFILE    HANDLE
+	HFONT           HANDLE
+	HGDIOBJ         HANDLE
+	HGLOBAL         HANDLE
+	HGLRC           HANDLE
+	HHOOK           HANDLE
+	HICON           HANDLE
+	HIMAGELIST      HANDLE
+	HINSTANCE       HANDLE
+	HKEY            HANDLE
+	HKL             HANDLE
+	HMENU           HANDLE
+	HMODULE         HANDLE
+	HMONITOR        HANDLE
+	HPEN            HANDLE
+	HRESULT         int32
+	HRGN            HANDLE
+	HRSRC           HANDLE
+	HTHUMBNAIL      HANDLE
+	HWND            HANDLE
+	LPARAM          uintptr
+	LPCVOID         unsafe.Pointer
+	LRESULT         uintptr
+	PVOID           unsafe.Pointer
+	QPC_TIME        uint64
+	ULONG_PTR       uintptr
+	WPARAM          uintptr
+	TRACEHANDLE     uintptr
+)
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162805.aspx
+type POINT struct {
+	X, Y int32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162897.aspx
+type RECT struct {
+	Left, Top, Right, Bottom int32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/ms633577.aspx
+type WNDCLASSEX struct {
+	Size       uint32
+	Style      uint32
+	WndProc    uintptr
+	ClsExtra   int32
+	WndExtra   int32
+	Instance   HINSTANCE
+	Icon       HICON
+	Cursor     HCURSOR
+	Background HBRUSH
+	MenuName   *uint16
+	ClassName  *uint16
+	IconSm     HICON
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/ms644958.aspx
+type MSG struct {
+	Hwnd    HWND
+	Message uint32
+	WParam  uintptr
+	LParam  uintptr
+	Time    uint32
+	Pt      POINT
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/dd145037.aspx
+type LOGFONT struct {
+	Height         int32
+	Width          int32
+	Escapement     int32
+	Orientation    int32
+	Weight         int32
+	Italic         byte
+	Underline      byte
+	StrikeOut      byte
+	CharSet        byte
+	OutPrecision   byte
+	ClipPrecision  byte
+	Quality        byte
+	PitchAndFamily byte
+	FaceName       [LF_FACESIZE]uint16
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646839.aspx
+type OPENFILENAME struct {
+	StructSize      uint32
+	Owner           HWND
+	Instance        HINSTANCE
+	Filter          *uint16
+	CustomFilter    *uint16
+	MaxCustomFilter uint32
+	FilterIndex     uint32
+	File            *uint16
+	MaxFile         uint32
+	FileTitle       *uint16
+	MaxFileTitle    uint32
+	InitialDir      *uint16
+	Title           *uint16
+	Flags           uint32
+	FileOffset      uint16
+	FileExtension   uint16
+	DefExt          *uint16
+	CustData        uintptr
+	FnHook          uintptr
+	TemplateName    *uint16
+	PvReserved      unsafe.Pointer
+	DwReserved      uint32
+	FlagsEx         uint32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/bb773205.aspx
+type BROWSEINFO struct {
+	Owner        HWND
+	Root         *uint16
+	DisplayName  *uint16
+	Title        *uint16
+	Flags        uint32
+	CallbackFunc uintptr
+	LParam       uintptr
+	Image        int32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/aa373931.aspx
+type GUID struct {
+	Data1 uint32
+	Data2 uint16
+	Data3 uint16
+	Data4 [8]byte
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/ms221627.aspx
+type VARIANT struct {
+	VT         uint16 //  2
+	WReserved1 uint16 //  4
+	WReserved2 uint16 //  6
+	WReserved3 uint16 //  8
+	Val        int64  // 16
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/ms221416.aspx
+type DISPPARAMS struct {
+	Rgvarg            uintptr
+	RgdispidNamedArgs uintptr
+	CArgs             uint32
+	CNamedArgs        uint32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/ms221133.aspx
+type EXCEPINFO struct {
+	WCode             uint16
+	WReserved         uint16
+	BstrSource        *uint16
+	BstrDescription   *uint16
+	BstrHelpFile      *uint16
+	DwHelpContext     uint32
+	PvReserved        uintptr
+	PfnDeferredFillIn uintptr
+	Scode             int32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/dd145035.aspx
+type LOGBRUSH struct {
+	LbStyle uint32
+	LbColor COLORREF
+	LbHatch uintptr
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183565.aspx
+type DEVMODE struct {
+	DmDeviceName       [CCHDEVICENAME]uint16
+	DmSpecVersion      uint16
+	DmDriverVersion    uint16
+	DmSize             uint16
+	DmDriverExtra      uint16
+	DmFields           uint32
+	DmOrientation      int16
+	DmPaperSize        int16
+	DmPaperLength      int16
+	DmPaperWidth       int16
+	DmScale            int16
+	DmCopies           int16
+	DmDefaultSource    int16
+	DmPrintQuality     int16
+	DmColor            int16
+	DmDuplex           int16
+	DmYResolution      int16
+	DmTTOption         int16
+	DmCollate          int16
+	DmFormName         [CCHFORMNAME]uint16
+	DmLogPixels        uint16
+	DmBitsPerPel       uint32
+	DmPelsWidth        uint32
+	DmPelsHeight       uint32
+	DmDisplayFlags     uint32
+	DmDisplayFrequency uint32
+	DmICMMethod        uint32
+	DmICMIntent        uint32
+	DmMediaType        uint32
+	DmDitherType       uint32
+	DmReserved1        uint32
+	DmReserved2        uint32
+	DmPanningWidth     uint32
+	DmPanningHeight    uint32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183376.aspx
+type BITMAPINFOHEADER struct {
+	BiSize          uint32
+	BiWidth         int32
+	BiHeight        int32
+	BiPlanes        uint16
+	BiBitCount      uint16
+	BiCompression   uint32
+	BiSizeImage     uint32
+	BiXPelsPerMeter int32
+	BiYPelsPerMeter int32
+	BiClrUsed       uint32
+	BiClrImportant  uint32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162938.aspx
+type RGBQUAD struct {
+	RgbBlue     byte
+	RgbGreen    byte
+	RgbRed      byte
+	RgbReserved byte
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183375.aspx
+type BITMAPINFO struct {
+	BmiHeader BITMAPINFOHEADER
+	BmiColors *RGBQUAD
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183371.aspx
+type BITMAP struct {
+	BmType       int32
+	BmWidth      int32
+	BmHeight     int32
+	BmWidthBytes int32
+	BmPlanes     uint16
+	BmBitsPixel  uint16
+	BmBits       unsafe.Pointer
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183567.aspx
+type DIBSECTION struct {
+	DsBm        BITMAP
+	DsBmih      BITMAPINFOHEADER
+	DsBitfields [3]uint32
+	DshSection  HANDLE
+	DsOffset    uint32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162607.aspx
+type ENHMETAHEADER struct {
+	IType          uint32
+	NSize          uint32
+	RclBounds      RECT
+	RclFrame       RECT
+	DSignature     uint32
+	NVersion       uint32
+	NBytes         uint32
+	NRecords       uint32
+	NHandles       uint16
+	SReserved      uint16
+	NDescription   uint32
+	OffDescription uint32
+	NPalEntries    uint32
+	SzlDevice      SIZE
+	SzlMillimeters SIZE
+	CbPixelFormat  uint32
+	OffPixelFormat uint32
+	BOpenGL        uint32
+	SzlMicrometers SIZE
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/dd145106.aspx
+type SIZE struct {
+	CX, CY int32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/dd145132.aspx
+type TEXTMETRIC struct {
+	TmHeight           int32
+	TmAscent           int32
+	TmDescent          int32
+	TmInternalLeading  int32
+	TmExternalLeading  int32
+	TmAveCharWidth     int32
+	TmMaxCharWidth     int32
+	TmWeight           int32
+	TmOverhang         int32
+	TmDigitizedAspectX int32
+	TmDigitizedAspectY int32
+	TmFirstChar        uint16
+	TmLastChar         uint16
+	TmDefaultChar      uint16
+	TmBreakChar        uint16
+	TmItalic           byte
+	TmUnderlined       byte
+	TmStruckOut        byte
+	TmPitchAndFamily   byte
+	TmCharSet          byte
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183574.aspx
+type DOCINFO struct {
+	CbSize       int32
+	LpszDocName  *uint16
+	LpszOutput   *uint16
+	LpszDatatype *uint16
+	FwType       uint32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/bb775514.aspx
+type NMHDR struct {
+	HwndFrom HWND
+	IdFrom   uintptr
+	Code     uint32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774743.aspx
+type LVCOLUMN struct {
+	Mask       uint32
+	Fmt        int32
+	Cx         int32
+	PszText    *uint16
+	CchTextMax int32
+	ISubItem   int32
+	IImage     int32
+	IOrder     int32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774760.aspx
+type LVITEM struct {
+	Mask       uint32
+	IItem      int32
+	ISubItem   int32
+	State      uint32
+	StateMask  uint32
+	PszText    *uint16
+	CchTextMax int32
+	IImage     int32
+	LParam     uintptr
+	IIndent    int32
+	IGroupId   int32
+	CColumns   uint32
+	PuColumns  uint32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774754.aspx
+type LVHITTESTINFO struct {
+	Pt       POINT
+	Flags    uint32
+	IItem    int32
+	ISubItem int32
+	IGroup   int32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774771.aspx
+type NMITEMACTIVATE struct {
+	Hdr       NMHDR
+	IItem     int32
+	ISubItem  int32
+	UNewState uint32
+	UOldState uint32
+	UChanged  uint32
+	PtAction  POINT
+	LParam    uintptr
+	UKeyFlags uint32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774773.aspx
+type NMLISTVIEW struct {
+	Hdr       NMHDR
+	IItem     int32
+	ISubItem  int32
+	UNewState uint32
+	UOldState uint32
+	UChanged  uint32
+	PtAction  POINT
+	LParam    uintptr
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774780.aspx
+type NMLVDISPINFO struct {
+	Hdr  NMHDR
+	Item LVITEM
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/bb775507.aspx
+type INITCOMMONCONTROLSEX struct {
+	DwSize uint32
+	DwICC  uint32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/bb760256.aspx
+type TOOLINFO struct {
+	CbSize     uint32
+	UFlags     uint32
+	Hwnd       HWND
+	UId        uintptr
+	Rect       RECT
+	Hinst      HINSTANCE
+	LpszText   *uint16
+	LParam     uintptr
+	LpReserved unsafe.Pointer
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/ms645604.aspx
+type TRACKMOUSEEVENT struct {
+	CbSize      uint32
+	DwFlags     uint32
+	HwndTrack   HWND
+	DwHoverTime uint32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/ms534067.aspx
+type GdiplusStartupInput struct {
+	GdiplusVersion           uint32
+	DebugEventCallback       uintptr
+	SuppressBackgroundThread BOOL
+	SuppressExternalCodecs   BOOL
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/ms534068.aspx
+type GdiplusStartupOutput struct {
+	NotificationHook   uintptr
+	NotificationUnhook uintptr
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162768.aspx
+type PAINTSTRUCT struct {
+	Hdc         HDC
+	FErase      BOOL
+	RcPaint     RECT
+	FRestore    BOOL
+	FIncUpdate  BOOL
+	RgbReserved [32]byte
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/ms684225.aspx
+type MODULEENTRY32 struct {
+	Size         uint32
+	ModuleID     uint32
+	ProcessID    uint32
+	GlblcntUsage uint32
+	ProccntUsage uint32
+	ModBaseAddr  *uint8
+	ModBaseSize  uint32
+	HModule      HMODULE
+	SzModule     [MAX_MODULE_NAME32 + 1]uint16
+	SzExePath    [MAX_PATH]uint16
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/ms724284.aspx
+type FILETIME struct {
+	DwLowDateTime  uint32
+	DwHighDateTime uint32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/ms682119.aspx
+type COORD struct {
+	X, Y int16
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/ms686311.aspx
+type SMALL_RECT struct {
+	Left, Top, Right, Bottom int16
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/ms682093.aspx
+type CONSOLE_SCREEN_BUFFER_INFO struct {
+	DwSize              COORD
+	DwCursorPosition    COORD
+	WAttributes         uint16
+	SrWindow            SMALL_RECT
+	DwMaximumWindowSize COORD
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/bb773244.aspx
+type MARGINS struct {
+	CxLeftWidth, CxRightWidth, CyTopHeight, CyBottomHeight int32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/aa969500.aspx
+type DWM_BLURBEHIND struct {
+	DwFlags                uint32
+	fEnable                BOOL
+	hRgnBlur               HRGN
+	fTransitionOnMaximized BOOL
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/aa969501.aspx
+type DWM_PRESENT_PARAMETERS struct {
+	cbSize             uint32
+	fQueue             BOOL
+	cRefreshStart      DWM_FRAME_COUNT
+	cBuffer            uint32
+	fUseSourceRate     BOOL
+	rateSource         UNSIGNED_RATIO
+	cRefreshesPerFrame uint32
+	eSampling          DWM_SOURCE_FRAME_SAMPLING
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/aa969502.aspx
+type DWM_THUMBNAIL_PROPERTIES struct {
+	dwFlags               uint32
+	rcDestination         RECT
+	rcSource              RECT
+	opacity               byte
+	fVisible              BOOL
+	fSourceClientAreaOnly BOOL
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/aa969503.aspx
+type DWM_TIMING_INFO struct {
+	cbSize                 uint32
+	rateRefresh            UNSIGNED_RATIO
+	qpcRefreshPeriod       QPC_TIME
+	rateCompose            UNSIGNED_RATIO
+	qpcVBlank              QPC_TIME
+	cRefresh               DWM_FRAME_COUNT
+	cDXRefresh             uint32
+	qpcCompose             QPC_TIME
+	cFrame                 DWM_FRAME_COUNT
+	cDXPresent             uint32
+	cRefreshFrame          DWM_FRAME_COUNT
+	cFrameSubmitted        DWM_FRAME_COUNT
+	cDXPresentSubmitted    uint32
+	cFrameConfirmed        DWM_FRAME_COUNT
+	cDXPresentConfirmed    uint32
+	cRefreshConfirmed      DWM_FRAME_COUNT
+	cDXRefreshConfirmed    uint32
+	cFramesLate            DWM_FRAME_COUNT
+	cFramesOutstanding     uint32
+	cFrameDisplayed        DWM_FRAME_COUNT
+	qpcFrameDisplayed      QPC_TIME
+	cRefreshFrameDisplayed DWM_FRAME_COUNT
+	cFrameComplete         DWM_FRAME_COUNT
+	qpcFrameComplete       QPC_TIME
+	cFramePending          DWM_FRAME_COUNT
+	qpcFramePending        QPC_TIME
+	cFramesDisplayed       DWM_FRAME_COUNT
+	cFramesComplete        DWM_FRAME_COUNT
+	cFramesPending         DWM_FRAME_COUNT
+	cFramesAvailable       DWM_FRAME_COUNT
+	cFramesDropped         DWM_FRAME_COUNT
+	cFramesMissed          DWM_FRAME_COUNT
+	cRefreshNextDisplayed  DWM_FRAME_COUNT
+	cRefreshNextPresented  DWM_FRAME_COUNT
+	cRefreshesDisplayed    DWM_FRAME_COUNT
+	cRefreshesPresented    DWM_FRAME_COUNT
+	cRefreshStarted        DWM_FRAME_COUNT
+	cPixelsReceived        uint64
+	cPixelsDrawn           uint64
+	cBuffersEmpty          DWM_FRAME_COUNT
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/dd389402.aspx
+type MilMatrix3x2D struct {
+	S_11, S_12, S_21, S_22 float64
+	DX, DY                 float64
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/aa969505.aspx
+type UNSIGNED_RATIO struct {
+	uiNumerator   uint32
+	uiDenominator uint32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/ms632603.aspx
+type CREATESTRUCT struct {
+	CreateParams uintptr
+	Instance     HINSTANCE
+	Menu         HMENU
+	Parent       HWND
+	Cy, Cx       int32
+	Y, X         int32
+	Style        int32
+	Name         *uint16
+	Class        *uint16
+	dwExStyle    uint32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/dd145065.aspx
+type MONITORINFO struct {
+	CbSize    uint32
+	RcMonitor RECT
+	RcWork    RECT
+	DwFlags   uint32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/dd145066.aspx
+type MONITORINFOEX struct {
+	MONITORINFO
+	SzDevice [CCHDEVICENAME]uint16
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/dd368826.aspx
+type PIXELFORMATDESCRIPTOR struct {
+	Size                   uint16
+	Version                uint16
+	DwFlags                uint32
+	IPixelType             byte
+	ColorBits              byte
+	RedBits, RedShift      byte
+	GreenBits, GreenShift  byte
+	BlueBits, BlueShift    byte
+	AlphaBits, AlphaShift  byte
+	AccumBits              byte
+	AccumRedBits           byte
+	AccumGreenBits         byte
+	AccumBlueBits          byte
+	AccumAlphaBits         byte
+	DepthBits, StencilBits byte
+	AuxBuffers             byte
+	ILayerType             byte
+	Reserved               byte
+	DwLayerMask            uint32
+	DwVisibleMask          uint32
+	DwDamageMask           uint32
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646270(v=vs.85).aspx
+type INPUT struct {
+	Type uint32
+	Mi   MOUSEINPUT
+	Ki   KEYBDINPUT
+	Hi   HARDWAREINPUT
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646273(v=vs.85).aspx
+type MOUSEINPUT struct {
+	Dx          int32
+	Dy          int32
+	MouseData   uint32
+	DwFlags     uint32
+	Time        uint32
+	DwExtraInfo uintptr
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646271(v=vs.85).aspx
+type KEYBDINPUT struct {
+	WVk         uint16
+	WScan       uint16
+	DwFlags     uint32
+	Time        uint32
+	DwExtraInfo uintptr
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646269(v=vs.85).aspx
+type HARDWAREINPUT struct {
+	UMsg    uint32
+	WParamL uint16
+	WParamH uint16
+}
+
+type KbdInput struct {
+	typ uint32
+	ki  KEYBDINPUT
+}
+
+type MouseInput struct {
+	typ uint32
+	mi  MOUSEINPUT
+}
+
+type HardwareInput struct {
+	typ uint32
+	hi  HARDWAREINPUT
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/ms724950(v=vs.85).aspx
+type SYSTEMTIME struct {
+	Year         uint16
+	Month        uint16
+	DayOfWeek    uint16
+	Day          uint16
+	Hour         uint16
+	Minute       uint16
+	Second       uint16
+	Milliseconds uint16
+}
+
+// http://msdn.microsoft.com/en-us/library/windows/desktop/ms644967(v=vs.85).aspx
+type KBDLLHOOKSTRUCT struct {
+	VkCode      DWORD
+	ScanCode    DWORD
+	Flags       DWORD
+	Time        DWORD
+	DwExtraInfo ULONG_PTR
+}
+
+type HOOKPROC func(int, WPARAM, LPARAM) LRESULT
+
+// https://msdn.microsoft.com/en-us/library/windows/desktop/ms633498(v=vs.85).aspx
+type WNDENUMPROC func(HWND, LPARAM) LRESULT
diff --git a/packages/w32/user32.go b/packages/w32/user32.go
new file mode 100644
index 00000000..8286e894
--- /dev/null
+++ b/packages/w32/user32.go
@@ -0,0 +1,1046 @@
+// Copyright 2010-2012 The W32 Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package w32
+
+import (
+	"fmt"
+	"syscall"
+	"unsafe"
+)
+
+var (
+	moduser32 = syscall.NewLazyDLL("user32.dll")
+
+	procRegisterClassEx               = moduser32.NewProc("RegisterClassExW")
+	procLoadIcon                      = moduser32.NewProc("LoadIconW")
+	procLoadCursor                    = moduser32.NewProc("LoadCursorW")
+	procShowWindow                    = moduser32.NewProc("ShowWindow")
+	procUpdateWindow                  = moduser32.NewProc("UpdateWindow")
+	procCreateWindowEx                = moduser32.NewProc("CreateWindowExW")
+	procAdjustWindowRect              = moduser32.NewProc("AdjustWindowRect")
+	procAdjustWindowRectEx            = moduser32.NewProc("AdjustWindowRectEx")
+	procDestroyWindow                 = moduser32.NewProc("DestroyWindow")
+	procDefWindowProc                 = moduser32.NewProc("DefWindowProcW")
+	procDefDlgProc                    = moduser32.NewProc("DefDlgProcW")
+	procPostQuitMessage               = moduser32.NewProc("PostQuitMessage")
+	procGetMessage                    = moduser32.NewProc("GetMessageW")
+	procTranslateMessage              = moduser32.NewProc("TranslateMessage")
+	procDispatchMessage               = moduser32.NewProc("DispatchMessageW")
+	procSendMessage                   = moduser32.NewProc("SendMessageW")
+	procSendMessageTimeout            = moduser32.NewProc("SendMessageTimeout")
+	procPostMessage                   = moduser32.NewProc("PostMessageW")
+	procWaitMessage                   = moduser32.NewProc("WaitMessage")
+	procSetWindowText                 = moduser32.NewProc("SetWindowTextW")
+	procGetWindowTextLength           = moduser32.NewProc("GetWindowTextLengthW")
+	procGetWindowText                 = moduser32.NewProc("GetWindowTextW")
+	procGetWindowRect                 = moduser32.NewProc("GetWindowRect")
+	procMoveWindow                    = moduser32.NewProc("MoveWindow")
+	procScreenToClient                = moduser32.NewProc("ScreenToClient")
+	procCallWindowProc                = moduser32.NewProc("CallWindowProcW")
+	procSetWindowLong                 = moduser32.NewProc("SetWindowLongW")
+	procSetWindowLongPtr              = moduser32.NewProc("SetWindowLongW")
+	procGetWindowLong                 = moduser32.NewProc("GetWindowLongW")
+	procGetWindowLongPtr              = moduser32.NewProc("GetWindowLongW")
+	procEnableWindow                  = moduser32.NewProc("EnableWindow")
+	procIsWindowEnabled               = moduser32.NewProc("IsWindowEnabled")
+	procIsWindowVisible               = moduser32.NewProc("IsWindowVisible")
+	procSetFocus                      = moduser32.NewProc("SetFocus")
+	procInvalidateRect                = moduser32.NewProc("InvalidateRect")
+	procGetClientRect                 = moduser32.NewProc("GetClientRect")
+	procGetDC                         = moduser32.NewProc("GetDC")
+	procReleaseDC                     = moduser32.NewProc("ReleaseDC")
+	procSetCapture                    = moduser32.NewProc("SetCapture")
+	procReleaseCapture                = moduser32.NewProc("ReleaseCapture")
+	procGetWindowThreadProcessId      = moduser32.NewProc("GetWindowThreadProcessId")
+	procMessageBox                    = moduser32.NewProc("MessageBoxW")
+	procGetSystemMetrics              = moduser32.NewProc("GetSystemMetrics")
+	procCopyRect                      = moduser32.NewProc("CopyRect")
+	procEqualRect                     = moduser32.NewProc("EqualRect")
+	procInflateRect                   = moduser32.NewProc("InflateRect")
+	procIntersectRect                 = moduser32.NewProc("IntersectRect")
+	procIsRectEmpty                   = moduser32.NewProc("IsRectEmpty")
+	procOffsetRect                    = moduser32.NewProc("OffsetRect")
+	procPtInRect                      = moduser32.NewProc("PtInRect")
+	procSetRect                       = moduser32.NewProc("SetRect")
+	procSetRectEmpty                  = moduser32.NewProc("SetRectEmpty")
+	procSubtractRect                  = moduser32.NewProc("SubtractRect")
+	procUnionRect                     = moduser32.NewProc("UnionRect")
+	procCreateDialogParam             = moduser32.NewProc("CreateDialogParamW")
+	procDialogBoxParam                = moduser32.NewProc("DialogBoxParamW")
+	procGetDlgItem                    = moduser32.NewProc("GetDlgItem")
+	procDrawIcon                      = moduser32.NewProc("DrawIcon")
+	procClientToScreen                = moduser32.NewProc("ClientToScreen")
+	procIsDialogMessage               = moduser32.NewProc("IsDialogMessageW")
+	procIsWindow                      = moduser32.NewProc("IsWindow")
+	procEndDialog                     = moduser32.NewProc("EndDialog")
+	procPeekMessage                   = moduser32.NewProc("PeekMessageW")
+	procTranslateAccelerator          = moduser32.NewProc("TranslateAcceleratorW")
+	procSetWindowPos                  = moduser32.NewProc("SetWindowPos")
+	procFillRect                      = moduser32.NewProc("FillRect")
+	procDrawText                      = moduser32.NewProc("DrawTextW")
+	procAddClipboardFormatListener    = moduser32.NewProc("AddClipboardFormatListener")
+	procRemoveClipboardFormatListener = moduser32.NewProc("RemoveClipboardFormatListener")
+	procOpenClipboard                 = moduser32.NewProc("OpenClipboard")
+	procCloseClipboard                = moduser32.NewProc("CloseClipboard")
+	procEnumClipboardFormats          = moduser32.NewProc("EnumClipboardFormats")
+	procGetClipboardData              = moduser32.NewProc("GetClipboardData")
+	procSetClipboardData              = moduser32.NewProc("SetClipboardData")
+	procEmptyClipboard                = moduser32.NewProc("EmptyClipboard")
+	procGetClipboardFormatName        = moduser32.NewProc("GetClipboardFormatNameW")
+	procIsClipboardFormatAvailable    = moduser32.NewProc("IsClipboardFormatAvailable")
+	procBeginPaint                    = moduser32.NewProc("BeginPaint")
+	procEndPaint                      = moduser32.NewProc("EndPaint")
+	procGetKeyboardState              = moduser32.NewProc("GetKeyboardState")
+	procMapVirtualKey                 = moduser32.NewProc("MapVirtualKeyExW")
+	procGetAsyncKeyState              = moduser32.NewProc("GetAsyncKeyState")
+	procToAscii                       = moduser32.NewProc("ToAscii")
+	procSwapMouseButton               = moduser32.NewProc("SwapMouseButton")
+	procGetCursorPos                  = moduser32.NewProc("GetCursorPos")
+	procSetCursorPos                  = moduser32.NewProc("SetCursorPos")
+	procSetCursor                     = moduser32.NewProc("SetCursor")
+	procCreateIcon                    = moduser32.NewProc("CreateIcon")
+	procDestroyIcon                   = moduser32.NewProc("DestroyIcon")
+	procMonitorFromPoint              = moduser32.NewProc("MonitorFromPoint")
+	procMonitorFromRect               = moduser32.NewProc("MonitorFromRect")
+	procMonitorFromWindow             = moduser32.NewProc("MonitorFromWindow")
+	procGetMonitorInfo                = moduser32.NewProc("GetMonitorInfoW")
+	procEnumDisplayMonitors           = moduser32.NewProc("EnumDisplayMonitors")
+	procEnumDisplaySettingsEx         = moduser32.NewProc("EnumDisplaySettingsExW")
+	procChangeDisplaySettingsEx       = moduser32.NewProc("ChangeDisplaySettingsExW")
+	procSendInput                     = moduser32.NewProc("SendInput")
+	procSetWindowsHookEx              = moduser32.NewProc("SetWindowsHookExW")
+	procUnhookWindowsHookEx           = moduser32.NewProc("UnhookWindowsHookEx")
+	procCallNextHookEx                = moduser32.NewProc("CallNextHookEx")
+	procSetForegroundWindow           = moduser32.NewProc("SetForegroundWindow")
+	procFindWindowW                   = moduser32.NewProc("FindWindowW")
+	procFindWindowExW                 = moduser32.NewProc("FindWindowExW")
+	procGetClassName                  = moduser32.NewProc("GetClassNameW")
+	procEnumChildWindows              = moduser32.NewProc("EnumChildWindows")
+	procSetTimer                      = moduser32.NewProc("SetTimer")
+	procKillTimer                     = moduser32.NewProc("KillTimer")
+	procRedrawWindow                  = moduser32.NewProc("RedrawWindow")
+)
+
+func RegisterClassEx(wndClassEx *WNDCLASSEX) ATOM {
+	ret, _, _ := procRegisterClassEx.Call(uintptr(unsafe.Pointer(wndClassEx)))
+	return ATOM(ret)
+}
+
+func LoadIcon(instance HINSTANCE, iconName *uint16) HICON {
+	ret, _, _ := procLoadIcon.Call(
+		uintptr(instance),
+		uintptr(unsafe.Pointer(iconName)))
+
+	return HICON(ret)
+
+}
+
+func LoadCursor(instance HINSTANCE, cursorName *uint16) HCURSOR {
+	ret, _, _ := procLoadCursor.Call(
+		uintptr(instance),
+		uintptr(unsafe.Pointer(cursorName)))
+
+	return HCURSOR(ret)
+
+}
+
+func GetClassNameW(hwnd HWND) string {
+	buf := make([]uint16, 255)
+	procGetClassName.Call(
+		uintptr(hwnd),
+		uintptr(unsafe.Pointer(&buf[0])),
+		uintptr(255))
+
+	return syscall.UTF16ToString(buf)
+}
+
+func SetForegroundWindow(hwnd HWND) bool {
+	ret, _, _ := procSetForegroundWindow.Call(
+		uintptr(hwnd))
+
+	return ret != 0
+}
+
+func ShowWindow(hwnd HWND, cmdshow int) bool {
+	ret, _, _ := procShowWindow.Call(
+		uintptr(hwnd),
+		uintptr(cmdshow))
+
+	return ret != 0
+
+}
+
+func UpdateWindow(hwnd HWND) bool {
+	ret, _, _ := procUpdateWindow.Call(
+		uintptr(hwnd))
+	return ret != 0
+}
+
+func CreateWindowEx(exStyle uint, className, windowName *uint16,
+	style uint, x, y, width, height int, parent HWND, menu HMENU,
+	instance HINSTANCE, param unsafe.Pointer) HWND {
+	ret, _, _ := procCreateWindowEx.Call(
+		uintptr(exStyle),
+		uintptr(unsafe.Pointer(className)),
+		uintptr(unsafe.Pointer(windowName)),
+		uintptr(style),
+		uintptr(x),
+		uintptr(y),
+		uintptr(width),
+		uintptr(height),
+		uintptr(parent),
+		uintptr(menu),
+		uintptr(instance),
+		uintptr(param))
+
+	return HWND(ret)
+}
+
+func FindWindowExW(hwndParent, hwndChildAfter HWND, className, windowName *uint16) HWND {
+	ret, _, _ := procFindWindowExW.Call(
+		uintptr(hwndParent),
+		uintptr(hwndChildAfter),
+		uintptr(unsafe.Pointer(className)),
+		uintptr(unsafe.Pointer(windowName)))
+
+	return HWND(ret)
+}
+
+func FindWindowW(className, windowName *uint16) HWND {
+	ret, _, _ := procFindWindowW.Call(
+		uintptr(unsafe.Pointer(className)),
+		uintptr(unsafe.Pointer(windowName)))
+
+	return HWND(ret)
+}
+
+func EnumChildWindows(hWndParent HWND, lpEnumFunc WNDENUMPROC, lParam LPARAM) bool {
+	ret, _, _ := procEnumChildWindows.Call(
+		uintptr(hWndParent),
+		uintptr(syscall.NewCallback(lpEnumFunc)),
+		uintptr(lParam),
+	)
+
+	return ret != 0
+}
+
+func AdjustWindowRectEx(rect *RECT, style uint, menu bool, exStyle uint) bool {
+	ret, _, _ := procAdjustWindowRectEx.Call(
+		uintptr(unsafe.Pointer(rect)),
+		uintptr(style),
+		uintptr(BoolToBOOL(menu)),
+		uintptr(exStyle))
+
+	return ret != 0
+}
+
+func AdjustWindowRect(rect *RECT, style uint, menu bool) bool {
+	ret, _, _ := procAdjustWindowRect.Call(
+		uintptr(unsafe.Pointer(rect)),
+		uintptr(style),
+		uintptr(BoolToBOOL(menu)))
+
+	return ret != 0
+}
+
+func DestroyWindow(hwnd HWND) bool {
+	ret, _, _ := procDestroyWindow.Call(
+		uintptr(hwnd))
+
+	return ret != 0
+}
+
+func DefWindowProc(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr {
+	ret, _, _ := procDefWindowProc.Call(
+		uintptr(hwnd),
+		uintptr(msg),
+		wParam,
+		lParam)
+
+	return ret
+}
+
+func DefDlgProc(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr {
+	ret, _, _ := procDefDlgProc.Call(
+		uintptr(hwnd),
+		uintptr(msg),
+		wParam,
+		lParam)
+
+	return ret
+}
+
+func PostQuitMessage(exitCode int) {
+	procPostQuitMessage.Call(
+		uintptr(exitCode))
+}
+
+func GetMessage(msg *MSG, hwnd HWND, msgFilterMin, msgFilterMax uint32) int {
+	ret, _, _ := procGetMessage.Call(
+		uintptr(unsafe.Pointer(msg)),
+		uintptr(hwnd),
+		uintptr(msgFilterMin),
+		uintptr(msgFilterMax))
+
+	return int(ret)
+}
+
+func TranslateMessage(msg *MSG) bool {
+	ret, _, _ := procTranslateMessage.Call(
+		uintptr(unsafe.Pointer(msg)))
+
+	return ret != 0
+
+}
+
+func DispatchMessage(msg *MSG) uintptr {
+	ret, _, _ := procDispatchMessage.Call(
+		uintptr(unsafe.Pointer(msg)))
+
+	return ret
+
+}
+
+func SendMessage(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr {
+	ret, _, _ := procSendMessage.Call(
+		uintptr(hwnd),
+		uintptr(msg),
+		wParam,
+		lParam)
+
+	return ret
+}
+
+func SendMessageTimeout(hwnd HWND, msg uint32, wParam, lParam uintptr, fuFlags, uTimeout uint32) uintptr {
+	ret, _, _ := procSendMessageTimeout.Call(
+		uintptr(hwnd),
+		uintptr(msg),
+		wParam,
+		lParam,
+		uintptr(fuFlags),
+		uintptr(uTimeout))
+
+	return ret
+}
+
+func PostMessage(hwnd HWND, msg uint32, wParam, lParam uintptr) bool {
+	ret, _, _ := procPostMessage.Call(
+		uintptr(hwnd),
+		uintptr(msg),
+		wParam,
+		lParam)
+
+	return ret != 0
+}
+
+func WaitMessage() bool {
+	ret, _, _ := procWaitMessage.Call()
+	return ret != 0
+}
+
+func SetWindowText(hwnd HWND, text string) {
+	procSetWindowText.Call(
+		uintptr(hwnd),
+		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text))))
+}
+
+func GetWindowTextLength(hwnd HWND) int {
+	ret, _, _ := procGetWindowTextLength.Call(
+		uintptr(hwnd))
+
+	return int(ret)
+}
+
+func GetWindowText(hwnd HWND) string {
+	textLen := GetWindowTextLength(hwnd) + 1
+
+	buf := make([]uint16, textLen)
+	procGetWindowText.Call(
+		uintptr(hwnd),
+		uintptr(unsafe.Pointer(&buf[0])),
+		uintptr(textLen))
+
+	return syscall.UTF16ToString(buf)
+}
+
+func GetWindowRect(hwnd HWND) *RECT {
+	var rect RECT
+	procGetWindowRect.Call(
+		uintptr(hwnd),
+		uintptr(unsafe.Pointer(&rect)))
+
+	return &rect
+}
+
+func MoveWindow(hwnd HWND, x, y, width, height int, repaint bool) bool {
+	ret, _, _ := procMoveWindow.Call(
+		uintptr(hwnd),
+		uintptr(x),
+		uintptr(y),
+		uintptr(width),
+		uintptr(height),
+		uintptr(BoolToBOOL(repaint)))
+
+	return ret != 0
+
+}
+
+func ScreenToClient(hwnd HWND, x, y int) (X, Y int, ok bool) {
+	pt := POINT{X: int32(x), Y: int32(y)}
+	ret, _, _ := procScreenToClient.Call(
+		uintptr(hwnd),
+		uintptr(unsafe.Pointer(&pt)))
+
+	return int(pt.X), int(pt.Y), ret != 0
+}
+
+func CallWindowProc(preWndProc uintptr, hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr {
+	ret, _, _ := procCallWindowProc.Call(
+		preWndProc,
+		uintptr(hwnd),
+		uintptr(msg),
+		wParam,
+		lParam)
+
+	return ret
+}
+
+func SetWindowLong(hwnd HWND, index int, value uint32) uint32 {
+	ret, _, _ := procSetWindowLong.Call(
+		uintptr(hwnd),
+		uintptr(index),
+		uintptr(value))
+
+	return uint32(ret)
+}
+
+func SetWindowLongPtr(hwnd HWND, index int, value uintptr) uintptr {
+	ret, _, _ := procSetWindowLongPtr.Call(
+		uintptr(hwnd),
+		uintptr(index),
+		value)
+
+	return ret
+}
+
+func GetWindowLong(hwnd HWND, index int) int32 {
+	ret, _, _ := procGetWindowLong.Call(
+		uintptr(hwnd),
+		uintptr(index))
+
+	return int32(ret)
+}
+
+func GetWindowLongPtr(hwnd HWND, index int) uintptr {
+	ret, _, _ := procGetWindowLongPtr.Call(
+		uintptr(hwnd),
+		uintptr(index))
+
+	return ret
+}
+
+func EnableWindow(hwnd HWND, b bool) bool {
+	ret, _, _ := procEnableWindow.Call(
+		uintptr(hwnd),
+		uintptr(BoolToBOOL(b)))
+	return ret != 0
+}
+
+func IsWindowEnabled(hwnd HWND) bool {
+	ret, _, _ := procIsWindowEnabled.Call(
+		uintptr(hwnd))
+
+	return ret != 0
+}
+
+func IsWindowVisible(hwnd HWND) bool {
+	ret, _, _ := procIsWindowVisible.Call(
+		uintptr(hwnd))
+
+	return ret != 0
+}
+
+func SetFocus(hwnd HWND) HWND {
+	ret, _, _ := procSetFocus.Call(
+		uintptr(hwnd))
+
+	return HWND(ret)
+}
+
+func InvalidateRect(hwnd HWND, rect *RECT, erase bool) bool {
+	ret, _, _ := procInvalidateRect.Call(
+		uintptr(hwnd),
+		uintptr(unsafe.Pointer(rect)),
+		uintptr(BoolToBOOL(erase)))
+
+	return ret != 0
+}
+
+func GetClientRect(hwnd HWND) *RECT {
+	var rect RECT
+	ret, _, _ := procGetClientRect.Call(
+		uintptr(hwnd),
+		uintptr(unsafe.Pointer(&rect)))
+
+	if ret == 0 {
+		panic(fmt.Sprintf("GetClientRect(%d) failed", hwnd))
+	}
+
+	return &rect
+}
+
+func GetDC(hwnd HWND) HDC {
+	ret, _, _ := procGetDC.Call(
+		uintptr(hwnd))
+
+	return HDC(ret)
+}
+
+func ReleaseDC(hwnd HWND, hDC HDC) bool {
+	ret, _, _ := procReleaseDC.Call(
+		uintptr(hwnd),
+		uintptr(hDC))
+
+	return ret != 0
+}
+
+func SetCapture(hwnd HWND) HWND {
+	ret, _, _ := procSetCapture.Call(
+		uintptr(hwnd))
+
+	return HWND(ret)
+}
+
+func ReleaseCapture() bool {
+	ret, _, _ := procReleaseCapture.Call()
+
+	return ret != 0
+}
+
+func GetWindowThreadProcessId(hwnd HWND) (HANDLE, int) {
+	var processId int
+	ret, _, _ := procGetWindowThreadProcessId.Call(
+		uintptr(hwnd),
+		uintptr(unsafe.Pointer(&processId)))
+
+	return HANDLE(ret), processId
+}
+
+func MessageBox(hwnd HWND, title, caption string, flags uint) int {
+	ret, _, _ := procMessageBox.Call(
+		uintptr(hwnd),
+		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(title))),
+		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(caption))),
+		uintptr(flags))
+
+	return int(ret)
+}
+
+func GetSystemMetrics(index int) int {
+	ret, _, _ := procGetSystemMetrics.Call(
+		uintptr(index))
+
+	return int(ret)
+}
+
+func CopyRect(dst, src *RECT) bool {
+	ret, _, _ := procCopyRect.Call(
+		uintptr(unsafe.Pointer(dst)),
+		uintptr(unsafe.Pointer(src)))
+
+	return ret != 0
+}
+
+func EqualRect(rect1, rect2 *RECT) bool {
+	ret, _, _ := procEqualRect.Call(
+		uintptr(unsafe.Pointer(rect1)),
+		uintptr(unsafe.Pointer(rect2)))
+
+	return ret != 0
+}
+
+func InflateRect(rect *RECT, dx, dy int) bool {
+	ret, _, _ := procInflateRect.Call(
+		uintptr(unsafe.Pointer(rect)),
+		uintptr(dx),
+		uintptr(dy))
+
+	return ret != 0
+}
+
+func IntersectRect(dst, src1, src2 *RECT) bool {
+	ret, _, _ := procIntersectRect.Call(
+		uintptr(unsafe.Pointer(dst)),
+		uintptr(unsafe.Pointer(src1)),
+		uintptr(unsafe.Pointer(src2)))
+
+	return ret != 0
+}
+
+func IsRectEmpty(rect *RECT) bool {
+	ret, _, _ := procIsRectEmpty.Call(
+		uintptr(unsafe.Pointer(rect)))
+
+	return ret != 0
+}
+
+func OffsetRect(rect *RECT, dx, dy int) bool {
+	ret, _, _ := procOffsetRect.Call(
+		uintptr(unsafe.Pointer(rect)),
+		uintptr(dx),
+		uintptr(dy))
+
+	return ret != 0
+}
+
+func PtInRect(rect *RECT, x, y int) bool {
+	pt := POINT{X: int32(x), Y: int32(y)}
+	ret, _, _ := procPtInRect.Call(
+		uintptr(unsafe.Pointer(rect)),
+		uintptr(unsafe.Pointer(&pt)))
+
+	return ret != 0
+}
+
+func SetRect(rect *RECT, left, top, right, bottom int) bool {
+	ret, _, _ := procSetRect.Call(
+		uintptr(unsafe.Pointer(rect)),
+		uintptr(left),
+		uintptr(top),
+		uintptr(right),
+		uintptr(bottom))
+
+	return ret != 0
+}
+
+func SetRectEmpty(rect *RECT) bool {
+	ret, _, _ := procSetRectEmpty.Call(
+		uintptr(unsafe.Pointer(rect)))
+
+	return ret != 0
+}
+
+func SubtractRect(dst, src1, src2 *RECT) bool {
+	ret, _, _ := procSubtractRect.Call(
+		uintptr(unsafe.Pointer(dst)),
+		uintptr(unsafe.Pointer(src1)),
+		uintptr(unsafe.Pointer(src2)))
+
+	return ret != 0
+}
+
+func UnionRect(dst, src1, src2 *RECT) bool {
+	ret, _, _ := procUnionRect.Call(
+		uintptr(unsafe.Pointer(dst)),
+		uintptr(unsafe.Pointer(src1)),
+		uintptr(unsafe.Pointer(src2)))
+
+	return ret != 0
+}
+
+func CreateDialog(hInstance HINSTANCE, lpTemplate *uint16, hWndParent HWND, lpDialogProc uintptr) HWND {
+	ret, _, _ := procCreateDialogParam.Call(
+		uintptr(hInstance),
+		uintptr(unsafe.Pointer(lpTemplate)),
+		uintptr(hWndParent),
+		lpDialogProc,
+		0)
+
+	return HWND(ret)
+}
+
+func DialogBox(hInstance HINSTANCE, lpTemplateName *uint16, hWndParent HWND, lpDialogProc uintptr) int {
+	ret, _, _ := procDialogBoxParam.Call(
+		uintptr(hInstance),
+		uintptr(unsafe.Pointer(lpTemplateName)),
+		uintptr(hWndParent),
+		lpDialogProc,
+		0)
+
+	return int(ret)
+}
+
+func GetDlgItem(hDlg HWND, nIDDlgItem int) HWND {
+	ret, _, _ := procGetDlgItem.Call(
+		uintptr(unsafe.Pointer(hDlg)),
+		uintptr(nIDDlgItem))
+
+	return HWND(ret)
+}
+
+func DrawIcon(hDC HDC, x, y int, hIcon HICON) bool {
+	ret, _, _ := procDrawIcon.Call(
+		uintptr(unsafe.Pointer(hDC)),
+		uintptr(x),
+		uintptr(y),
+		uintptr(unsafe.Pointer(hIcon)))
+
+	return ret != 0
+}
+
+func ClientToScreen(hwnd HWND, x, y int) (int, int) {
+	pt := POINT{X: int32(x), Y: int32(y)}
+
+	procClientToScreen.Call(
+		uintptr(hwnd),
+		uintptr(unsafe.Pointer(&pt)))
+
+	return int(pt.X), int(pt.Y)
+}
+
+func IsDialogMessage(hwnd HWND, msg *MSG) bool {
+	ret, _, _ := procIsDialogMessage.Call(
+		uintptr(hwnd),
+		uintptr(unsafe.Pointer(msg)))
+
+	return ret != 0
+}
+
+func IsWindow(hwnd HWND) bool {
+	ret, _, _ := procIsWindow.Call(
+		uintptr(hwnd))
+
+	return ret != 0
+}
+
+func EndDialog(hwnd HWND, nResult uintptr) bool {
+	ret, _, _ := procEndDialog.Call(
+		uintptr(hwnd),
+		nResult)
+
+	return ret != 0
+}
+
+func PeekMessage(lpMsg *MSG, hwnd HWND, wMsgFilterMin, wMsgFilterMax, wRemoveMsg uint32) bool {
+	ret, _, _ := procPeekMessage.Call(
+		uintptr(unsafe.Pointer(lpMsg)),
+		uintptr(hwnd),
+		uintptr(wMsgFilterMin),
+		uintptr(wMsgFilterMax),
+		uintptr(wRemoveMsg))
+
+	return ret != 0
+}
+
+func TranslateAccelerator(hwnd HWND, hAccTable HACCEL, lpMsg *MSG) bool {
+	ret, _, _ := procTranslateAccelerator.Call(
+		uintptr(hwnd),
+		uintptr(hAccTable),
+		uintptr(unsafe.Pointer(lpMsg)))
+
+	return ret != 0
+}
+
+func SetWindowPos(hwnd, hWndInsertAfter HWND, x, y, cx, cy int, uFlags uint) bool {
+	ret, _, _ := procSetWindowPos.Call(
+		uintptr(hwnd),
+		uintptr(hWndInsertAfter),
+		uintptr(x),
+		uintptr(y),
+		uintptr(cx),
+		uintptr(cy),
+		uintptr(uFlags))
+
+	return ret != 0
+}
+
+func FillRect(hDC HDC, lprc *RECT, hbr HBRUSH) bool {
+	ret, _, _ := procFillRect.Call(
+		uintptr(hDC),
+		uintptr(unsafe.Pointer(lprc)),
+		uintptr(hbr))
+
+	return ret != 0
+}
+
+func DrawText(hDC HDC, text string, uCount int, lpRect *RECT, uFormat uint) int {
+	ret, _, _ := procDrawText.Call(
+		uintptr(hDC),
+		uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text))),
+		uintptr(uCount),
+		uintptr(unsafe.Pointer(lpRect)),
+		uintptr(uFormat))
+
+	return int(ret)
+}
+
+func AddClipboardFormatListener(hwnd HWND) bool {
+	ret, _, _ := procAddClipboardFormatListener.Call(
+		uintptr(hwnd))
+	return ret != 0
+}
+
+func RemoveClipboardFormatListener(hwnd HWND) bool {
+	ret, _, _ := procRemoveClipboardFormatListener.Call(
+		uintptr(hwnd))
+	return ret != 0
+}
+
+func OpenClipboard(hWndNewOwner HWND) bool {
+	ret, _, _ := procOpenClipboard.Call(
+		uintptr(hWndNewOwner))
+	return ret != 0
+}
+
+func CloseClipboard() bool {
+	ret, _, _ := procCloseClipboard.Call()
+	return ret != 0
+}
+
+func EnumClipboardFormats(format uint) uint {
+	ret, _, _ := procEnumClipboardFormats.Call(
+		uintptr(format))
+	return uint(ret)
+}
+
+func GetClipboardData(uFormat uint) HANDLE {
+	ret, _, _ := procGetClipboardData.Call(
+		uintptr(uFormat))
+	return HANDLE(ret)
+}
+
+func SetClipboardData(uFormat uint, hMem HANDLE) HANDLE {
+	ret, _, _ := procSetClipboardData.Call(
+		uintptr(uFormat),
+		uintptr(hMem))
+	return HANDLE(ret)
+}
+
+func EmptyClipboard() bool {
+	ret, _, _ := procEmptyClipboard.Call()
+	return ret != 0
+}
+
+func GetClipboardFormatName(format uint) (string, bool) {
+	cchMaxCount := 255
+	buf := make([]uint16, cchMaxCount)
+	ret, _, _ := procGetClipboardFormatName.Call(
+		uintptr(format),
+		uintptr(unsafe.Pointer(&buf[0])),
+		uintptr(cchMaxCount))
+
+	if ret > 0 {
+		return syscall.UTF16ToString(buf), true
+	}
+
+	return "Requested format does not exist or is predefined", false
+}
+
+func IsClipboardFormatAvailable(format uint) bool {
+	ret, _, _ := procIsClipboardFormatAvailable.Call(uintptr(format))
+	return ret != 0
+}
+
+func BeginPaint(hwnd HWND, paint *PAINTSTRUCT) HDC {
+	ret, _, _ := procBeginPaint.Call(
+		uintptr(hwnd),
+		uintptr(unsafe.Pointer(paint)))
+	return HDC(ret)
+}
+
+func EndPaint(hwnd HWND, paint *PAINTSTRUCT) {
+	procEndPaint.Call(
+		uintptr(hwnd),
+		uintptr(unsafe.Pointer(paint)))
+}
+
+func GetKeyboardState(lpKeyState *[]byte) bool {
+	ret, _, _ := procGetKeyboardState.Call(
+		uintptr(unsafe.Pointer(&(*lpKeyState)[0])))
+	return ret != 0
+}
+
+func MapVirtualKeyEx(uCode, uMapType uint, dwhkl HKL) uint {
+	ret, _, _ := procMapVirtualKey.Call(
+		uintptr(uCode),
+		uintptr(uMapType),
+		uintptr(dwhkl))
+	return uint(ret)
+}
+
+func GetAsyncKeyState(vKey int) uint16 {
+	ret, _, _ := procGetAsyncKeyState.Call(uintptr(vKey))
+	return uint16(ret)
+}
+
+func ToAscii(uVirtKey, uScanCode uint, lpKeyState *byte, lpChar *uint16, uFlags uint) int {
+	ret, _, _ := procToAscii.Call(
+		uintptr(uVirtKey),
+		uintptr(uScanCode),
+		uintptr(unsafe.Pointer(lpKeyState)),
+		uintptr(unsafe.Pointer(lpChar)),
+		uintptr(uFlags))
+	return int(ret)
+}
+
+func SwapMouseButton(fSwap bool) bool {
+	ret, _, _ := procSwapMouseButton.Call(
+		uintptr(BoolToBOOL(fSwap)))
+	return ret != 0
+}
+
+func GetCursorPos() (x, y int, ok bool) {
+	pt := POINT{}
+	ret, _, _ := procGetCursorPos.Call(uintptr(unsafe.Pointer(&pt)))
+	return int(pt.X), int(pt.Y), ret != 0
+}
+
+func SetCursorPos(x, y int) bool {
+	ret, _, _ := procSetCursorPos.Call(
+		uintptr(x),
+		uintptr(y),
+	)
+	return ret != 0
+}
+
+func SetCursor(cursor HCURSOR) HCURSOR {
+	ret, _, _ := procSetCursor.Call(
+		uintptr(cursor),
+	)
+	return HCURSOR(ret)
+}
+
+func CreateIcon(instance HINSTANCE, nWidth, nHeight int, cPlanes, cBitsPerPixel byte, ANDbits, XORbits *byte) HICON {
+	ret, _, _ := procCreateIcon.Call(
+		uintptr(instance),
+		uintptr(nWidth),
+		uintptr(nHeight),
+		uintptr(cPlanes),
+		uintptr(cBitsPerPixel),
+		uintptr(unsafe.Pointer(ANDbits)),
+		uintptr(unsafe.Pointer(XORbits)),
+	)
+	return HICON(ret)
+}
+
+func DestroyIcon(icon HICON) bool {
+	ret, _, _ := procDestroyIcon.Call(
+		uintptr(icon),
+	)
+	return ret != 0
+}
+
+func MonitorFromPoint(x, y int, dwFlags uint32) HMONITOR {
+	ret, _, _ := procMonitorFromPoint.Call(
+		uintptr(x),
+		uintptr(y),
+		uintptr(dwFlags),
+	)
+	return HMONITOR(ret)
+}
+
+func MonitorFromRect(rc *RECT, dwFlags uint32) HMONITOR {
+	ret, _, _ := procMonitorFromRect.Call(
+		uintptr(unsafe.Pointer(rc)),
+		uintptr(dwFlags),
+	)
+	return HMONITOR(ret)
+}
+
+func MonitorFromWindow(hwnd HWND, dwFlags uint32) HMONITOR {
+	ret, _, _ := procMonitorFromWindow.Call(
+		uintptr(hwnd),
+		uintptr(dwFlags),
+	)
+	return HMONITOR(ret)
+}
+
+func GetMonitorInfo(hMonitor HMONITOR, lmpi *MONITORINFO) bool {
+	ret, _, _ := procGetMonitorInfo.Call(
+		uintptr(hMonitor),
+		uintptr(unsafe.Pointer(lmpi)),
+	)
+	return ret != 0
+}
+
+func EnumDisplayMonitors(hdc HDC, clip *RECT, fnEnum, dwData uintptr) bool {
+	ret, _, _ := procEnumDisplayMonitors.Call(
+		uintptr(hdc),
+		uintptr(unsafe.Pointer(clip)),
+		fnEnum,
+		dwData,
+	)
+	return ret != 0
+}
+
+func EnumDisplaySettingsEx(szDeviceName *uint16, iModeNum uint32, devMode *DEVMODE, dwFlags uint32) bool {
+	ret, _, _ := procEnumDisplaySettingsEx.Call(
+		uintptr(unsafe.Pointer(szDeviceName)),
+		uintptr(iModeNum),
+		uintptr(unsafe.Pointer(devMode)),
+		uintptr(dwFlags),
+	)
+	return ret != 0
+}
+
+func ChangeDisplaySettingsEx(szDeviceName *uint16, devMode *DEVMODE, hwnd HWND, dwFlags uint32, lParam uintptr) int32 {
+	ret, _, _ := procChangeDisplaySettingsEx.Call(
+		uintptr(unsafe.Pointer(szDeviceName)),
+		uintptr(unsafe.Pointer(devMode)),
+		uintptr(hwnd),
+		uintptr(dwFlags),
+		lParam,
+	)
+	return int32(ret)
+}
+
+func SetWindowsHookEx(idHook int, lpfn HOOKPROC, hMod HINSTANCE, dwThreadId DWORD) HHOOK {
+	ret, _, _ := procSetWindowsHookEx.Call(
+		uintptr(idHook),
+		uintptr(syscall.NewCallback(lpfn)),
+		uintptr(hMod),
+		uintptr(dwThreadId),
+	)
+	return HHOOK(ret)
+}
+
+func UnhookWindowsHookEx(hhk HHOOK) bool {
+	ret, _, _ := procUnhookWindowsHookEx.Call(
+		uintptr(hhk),
+	)
+	return ret != 0
+}
+
+func CallNextHookEx(hhk HHOOK, nCode int, wParam WPARAM, lParam LPARAM) LRESULT {
+	ret, _, _ := procCallNextHookEx.Call(
+		uintptr(hhk),
+		uintptr(nCode),
+		uintptr(wParam),
+		uintptr(lParam),
+	)
+	return LRESULT(ret)
+}
+
+func SetTimer(hwnd HWND, nIDEvent uint32, uElapse uint32, lpTimerProc uintptr) uintptr {
+	ret, _, _ := procSetTimer.Call(
+		uintptr(hwnd),
+		uintptr(nIDEvent),
+		uintptr(uElapse),
+		lpTimerProc,
+	)
+	return ret
+}
+
+func KillTimer(hwnd HWND, nIDEvent uint32) bool {
+	ret, _, _ := procKillTimer.Call(
+		uintptr(hwnd),
+		uintptr(nIDEvent),
+	)
+	return ret != 0
+}
+
+// it will panic when the function fails
+func RedrawWindow(hWnd HWND, lpRect *RECT, hrgnUpdate HRGN, flag uint32) {
+	ret, _, _ := procRedrawWindow.Call(
+		uintptr(hWnd),
+		uintptr(unsafe.Pointer(lpRect)),
+		uintptr(hrgnUpdate),
+		uintptr(flag),
+	)
+	if ret!=0{
+		panic("RedrawWindow fail")
+	}
+	return
+}
\ No newline at end of file
diff --git a/packages/w32/utils.go b/packages/w32/utils.go
new file mode 100644
index 00000000..4fb5b6c2
--- /dev/null
+++ b/packages/w32/utils.go
@@ -0,0 +1,201 @@
+// Copyright 2010-2012 The W32 Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package w32
+
+import (
+	"syscall"
+	"unicode/utf16"
+	"unsafe"
+)
+
+func MakeIntResource(id uint16) *uint16 {
+	return (*uint16)(unsafe.Pointer(uintptr(id)))
+}
+
+func LOWORD(dw uint32) uint16 {
+	return uint16(dw)
+}
+
+func HIWORD(dw uint32) uint16 {
+	return uint16(dw >> 16 & 0xffff)
+}
+
+func BoolToBOOL(value bool) BOOL {
+	if value {
+		return 1
+	}
+
+	return 0
+}
+
+func UTF16PtrToString(cstr *uint16) string {
+	if cstr != nil {
+		us := make([]uint16, 0, 256)
+		for p := uintptr(unsafe.Pointer(cstr)); ; p += 2 {
+			u := *(*uint16)(unsafe.Pointer(p))
+			if u == 0 {
+				return string(utf16.Decode(us))
+			}
+			us = append(us, u)
+		}
+	}
+
+	return ""
+}
+
+func ComAddRef(unknown *IUnknown) int32 {
+	ret, _, _ := syscall.Syscall(unknown.lpVtbl.pAddRef, 1,
+		uintptr(unsafe.Pointer(unknown)),
+		0,
+		0)
+	return int32(ret)
+}
+
+func ComRelease(unknown *IUnknown) int32 {
+	ret, _, _ := syscall.Syscall(unknown.lpVtbl.pRelease, 1,
+		uintptr(unsafe.Pointer(unknown)),
+		0,
+		0)
+	return int32(ret)
+}
+
+func ComQueryInterface(unknown *IUnknown, id *GUID) *IDispatch {
+	var disp *IDispatch
+	hr, _, _ := syscall.Syscall(unknown.lpVtbl.pQueryInterface, 3,
+		uintptr(unsafe.Pointer(unknown)),
+		uintptr(unsafe.Pointer(id)),
+		uintptr(unsafe.Pointer(&disp)))
+	if hr != 0 {
+		panic("Invoke QieryInterface error.")
+	}
+	return disp
+}
+
+func ComGetIDsOfName(disp *IDispatch, names []string) []int32 {
+	wnames := make([]*uint16, len(names))
+	dispid := make([]int32, len(names))
+	for i := 0; i < len(names); i++ {
+		wnames[i] = syscall.StringToUTF16Ptr(names[i])
+	}
+	hr, _, _ := syscall.Syscall6(disp.lpVtbl.pGetIDsOfNames, 6,
+		uintptr(unsafe.Pointer(disp)),
+		uintptr(unsafe.Pointer(IID_NULL)),
+		uintptr(unsafe.Pointer(&wnames[0])),
+		uintptr(len(names)),
+		uintptr(GetUserDefaultLCID()),
+		uintptr(unsafe.Pointer(&dispid[0])))
+	if hr != 0 {
+		panic("Invoke GetIDsOfName error.")
+	}
+	return dispid
+}
+
+func ComInvoke(disp *IDispatch, dispid int32, dispatch int16, params ...interface{}) (result *VARIANT) {
+	var dispparams DISPPARAMS
+
+	if dispatch&DISPATCH_PROPERTYPUT != 0 {
+		dispnames := [1]int32{DISPID_PROPERTYPUT}
+		dispparams.RgdispidNamedArgs = uintptr(unsafe.Pointer(&dispnames[0]))
+		dispparams.CNamedArgs = 1
+	}
+	var vargs []VARIANT
+	if len(params) > 0 {
+		vargs = make([]VARIANT, len(params))
+		for i, v := range params {
+			//n := len(params)-i-1
+			n := len(params) - i - 1
+			VariantInit(&vargs[n])
+			switch v.(type) {
+			case bool:
+				if v.(bool) {
+					vargs[n] = VARIANT{VT_BOOL, 0, 0, 0, 0xffff}
+				} else {
+					vargs[n] = VARIANT{VT_BOOL, 0, 0, 0, 0}
+				}
+			case *bool:
+				vargs[n] = VARIANT{VT_BOOL | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*bool))))}
+			case byte:
+				vargs[n] = VARIANT{VT_I1, 0, 0, 0, int64(v.(byte))}
+			case *byte:
+				vargs[n] = VARIANT{VT_I1 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*byte))))}
+			case int16:
+				vargs[n] = VARIANT{VT_I2, 0, 0, 0, int64(v.(int16))}
+			case *int16:
+				vargs[n] = VARIANT{VT_I2 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*int16))))}
+			case uint16:
+				vargs[n] = VARIANT{VT_UI2, 0, 0, 0, int64(v.(int16))}
+			case *uint16:
+				vargs[n] = VARIANT{VT_UI2 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*uint16))))}
+			case int, int32:
+				vargs[n] = VARIANT{VT_UI4, 0, 0, 0, int64(v.(int))}
+			case *int, *int32:
+				vargs[n] = VARIANT{VT_I4 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*int))))}
+			case uint, uint32:
+				vargs[n] = VARIANT{VT_UI4, 0, 0, 0, int64(v.(uint))}
+			case *uint, *uint32:
+				vargs[n] = VARIANT{VT_UI4 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*uint))))}
+			case int64:
+				vargs[n] = VARIANT{VT_I8, 0, 0, 0, v.(int64)}
+			case *int64:
+				vargs[n] = VARIANT{VT_I8 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*int64))))}
+			case uint64:
+				vargs[n] = VARIANT{VT_UI8, 0, 0, 0, int64(v.(uint64))}
+			case *uint64:
+				vargs[n] = VARIANT{VT_UI8 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*uint64))))}
+			case float32:
+				vargs[n] = VARIANT{VT_R4, 0, 0, 0, int64(v.(float32))}
+			case *float32:
+				vargs[n] = VARIANT{VT_R4 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*float32))))}
+			case float64:
+				vargs[n] = VARIANT{VT_R8, 0, 0, 0, int64(v.(float64))}
+			case *float64:
+				vargs[n] = VARIANT{VT_R8 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*float64))))}
+			case string:
+				vargs[n] = VARIANT{VT_BSTR, 0, 0, 0, int64(uintptr(unsafe.Pointer(SysAllocString(v.(string)))))}
+			case *string:
+				vargs[n] = VARIANT{VT_BSTR | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*string))))}
+			case *IDispatch:
+				vargs[n] = VARIANT{VT_DISPATCH, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*IDispatch))))}
+			case **IDispatch:
+				vargs[n] = VARIANT{VT_DISPATCH | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(**IDispatch))))}
+			case nil:
+				vargs[n] = VARIANT{VT_NULL, 0, 0, 0, 0}
+			case *VARIANT:
+				vargs[n] = VARIANT{VT_VARIANT | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*VARIANT))))}
+			default:
+				panic("unknown type")
+			}
+		}
+		dispparams.Rgvarg = uintptr(unsafe.Pointer(&vargs[0]))
+		dispparams.CArgs = uint32(len(params))
+	}
+
+	var ret VARIANT
+	var excepInfo EXCEPINFO
+	VariantInit(&ret)
+	hr, _, _ := syscall.Syscall9(disp.lpVtbl.pInvoke, 8,
+		uintptr(unsafe.Pointer(disp)),
+		uintptr(dispid),
+		uintptr(unsafe.Pointer(IID_NULL)),
+		uintptr(GetUserDefaultLCID()),
+		uintptr(dispatch),
+		uintptr(unsafe.Pointer(&dispparams)),
+		uintptr(unsafe.Pointer(&ret)),
+		uintptr(unsafe.Pointer(&excepInfo)),
+		0)
+	if hr != 0 {
+		if excepInfo.BstrDescription != nil {
+			bs := UTF16PtrToString(excepInfo.BstrDescription)
+			panic(bs)
+		}
+	}
+	for _, varg := range vargs {
+		if varg.VT == VT_BSTR && varg.Val != 0 {
+			SysFreeString(((*int16)(unsafe.Pointer(uintptr(varg.Val)))))
+		}
+	}
+	result = &ret
+	return
+}
diff --git a/packages/w32/vars.go b/packages/w32/vars.go
new file mode 100644
index 00000000..2dab2e39
--- /dev/null
+++ b/packages/w32/vars.go
@@ -0,0 +1,13 @@
+// Copyright 2010-2012 The W32 Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package w32
+
+var (
+	IID_NULL                      = &GUID{0x00000000, 0x0000, 0x0000, [8]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}
+	IID_IUnknown                  = &GUID{0x00000000, 0x0000, 0x0000, [8]byte{0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}
+	IID_IDispatch                 = &GUID{0x00020400, 0x0000, 0x0000, [8]byte{0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}
+	IID_IConnectionPointContainer = &GUID{0xB196B284, 0xBAB4, 0x101A, [8]byte{0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07}}
+	IID_IConnectionPoint          = &GUID{0xB196B286, 0xBAB4, 0x101A, [8]byte{0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07}}
+)
-- 
GitLab