{"id":32173,"date":"2006-02-23T10:00:14","date_gmt":"2006-02-23T10:00:14","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/oldnewthing\/2006\/02\/23\/enumerating-threads-in-a-process\/"},"modified":"2006-02-23T10:00:14","modified_gmt":"2006-02-23T10:00:14","slug":"enumerating-threads-in-a-process","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20060223-14\/?p=32173\/","title":{"rendered":"Enumerating threads in a process"},"content":{"rendered":"<p>\nThe\n<a HREF=\"http:\/\/msdn.microsoft.com\/library\/en-us\/perfmon\/base\/about_tool_help_functions.asp\">\ntool helper library<\/a> is sort of the black sheep of Win32.\nIt grew out of the 16-bit TOOLHELP library,\nwhich provided services for system debugging tools to do things\nlike take stack traces and\nenumerate all the memory in the system.\nThe original incarnation of Win32 didn&#8217;t incorporate it;\nit wasn&#8217;t until Windows&nbsp;95 that a 32-bit version of the\ntool helper library sort of got bolted onto the side of Win32.\n<\/p>\n<p>\nDisowned or not, the functions are still there, so let&#8217;s give them a spin.\n<\/p>\n<pre>\n#include &lt;stdio.h&gt;\n#include &lt;windows.h&gt;\n#include &lt;tlhelp32.h&gt;\nint __cdecl main(int argc, char **argv)\n{\n HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);\n if (h != INVALID_HANDLE_VALUE) {\n  THREADENTRY32 te;\n  te.dwSize = sizeof(te);\n  if (Thread32First(h, &amp;te)) {\n   do {\n     if (te.dwSize &gt;= FIELD_OFFSET(THREADENTRY32, th32OwnerProcessID) +\n                      sizeof(te.th32OwnerProcessID)) {\n       printf(\"Process 0x%04x Thread 0x%04x\\n\",\n             te.th32OwnerProcessID, te.th32ThreadID);\n     }\n   te.dwSize = sizeof(te);\n   } while (Thread32Next(h, &amp;te));\n  }\n  CloseHandle(h);\n }\n return 0;\n}\n<\/pre>\n<p>\nRunning this program prints a list of all the threads in the\nsystem (or at least all the ones you have access to).\nThis is particularly straightforward,\nthe only subtlety being the strange check that the size\nreturned by the <code>Thread32First<\/code> function\nis large enough to emcompass the <code>th32OwnerProcessID<\/code>\nfield that we need.\nThis complexity is necessary due to the somewhat\nunorthodox way that the\n<code>Thread32First<\/code> and <code>Thread32Next<\/code>\nfunctions\n<a HREF=\"http:\/\/blogs.msdn.com\/oldnewthing\/archive\/2003\/12\/12\/56061.aspx\">\ncheck structure sizes<\/a>.\n<\/p>\n<p>\nThat&#8217;s what happens when you&#8217;re the black sheep of the Win32&nbsp;API.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The tool helper library is sort of the black sheep of Win32. It grew out of the 16-bit TOOLHELP library, which provided services for system debugging tools to do things like take stack traces and enumerate all the memory in the system. The original incarnation of Win32 didn&#8217;t incorporate it; it wasn&#8217;t until Windows&nbsp;95 that [&hellip;]<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[25],"class_list":["post-32173","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-code"],"acf":[],"blog_post_summary":"<p>The tool helper library is sort of the black sheep of Win32. It grew out of the 16-bit TOOLHELP library, which provided services for system debugging tools to do things like take stack traces and enumerate all the memory in the system. The original incarnation of Win32 didn&#8217;t incorporate it; it wasn&#8217;t until Windows&nbsp;95 that [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/32173","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=32173"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/32173\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=32173"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=32173"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=32173"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}