WEBVTT

1
00:00:00.120 --> 00:00:03.759
<v Speaker 1>Welcome to the deep dive. Today. We're really peeling back

2
00:00:03.799 --> 00:00:06.080
<v Speaker 1>the layers of your Windows ten computer.

3
00:00:06.200 --> 00:00:07.599
<v Speaker 2>Yeah, going straight to the core.

4
00:00:07.639 --> 00:00:12.279
<v Speaker 1>Exactly how software actually interacts with the operating system. One

5
00:00:12.320 --> 00:00:14.960
<v Speaker 1>of you asked for a deeper look, and well, here.

6
00:00:14.800 --> 00:00:17.559
<v Speaker 2>We are, absolutely and we've got a really good technical

7
00:00:17.600 --> 00:00:19.960
<v Speaker 2>book to guide us. We'll be digging into the key

8
00:00:20.039 --> 00:00:22.679
<v Speaker 2>insights on the fundamental stuff.

9
00:00:22.480 --> 00:00:24.399
<v Speaker 1>Like processes, threads.

10
00:00:23.960 --> 00:00:27.719
<v Speaker 2>Right, memory management, and that crucial world of IO input

11
00:00:27.839 --> 00:00:29.000
<v Speaker 2>output operations.

12
00:00:29.440 --> 00:00:32.320
<v Speaker 1>Our mission then for this deep dive is to get

13
00:00:32.399 --> 00:00:35.200
<v Speaker 1>right to the heart of how Windows actually juggles all

14
00:00:35.280 --> 00:00:38.119
<v Speaker 1>the programs you run and the resources they all need.

15
00:00:38.240 --> 00:00:40.679
<v Speaker 2>We're aiming for those moments where it just clicks.

16
00:00:40.759 --> 00:00:43.520
<v Speaker 1>Yeah, those aha moments where you think, oh, that's why

17
00:00:43.560 --> 00:00:45.799
<v Speaker 1>my system does that. So let's start at the very

18
00:00:45.840 --> 00:00:47.280
<v Speaker 1>beginning processes.

19
00:00:47.359 --> 00:00:50.840
<v Speaker 2>Okay, so book right away makes this really important point.

20
00:00:50.840 --> 00:00:53.719
<v Speaker 2>It might even surprise you. We usually think of a

21
00:00:53.759 --> 00:00:57.200
<v Speaker 2>process as the thing that's running, but it's actually more

22
00:00:57.240 --> 00:01:01.200
<v Speaker 2>accurate to think of it as a management object, a container. Basically,

23
00:01:01.280 --> 00:01:05.560
<v Speaker 2>I contain yeah, the actual work, the code execution that's

24
00:01:05.599 --> 00:01:07.480
<v Speaker 2>done by threads within the process.

25
00:01:07.560 --> 00:01:11.400
<v Speaker 1>Okay, So processes are like maybe office buildings, and threads

26
00:01:11.480 --> 00:01:12.959
<v Speaker 1>are the workers inside.

27
00:01:13.040 --> 00:01:16.319
<v Speaker 2>That's a great analogy. Exactly one can't really function without

28
00:01:16.319 --> 00:01:18.640
<v Speaker 2>the other, but they definitely have distinct roles.

29
00:01:18.760 --> 00:01:22.079
<v Speaker 1>Interesting, So if the process isn't the runner, what does

30
00:01:22.120 --> 00:01:24.719
<v Speaker 1>it actually own what's inside this office building?

31
00:01:25.439 --> 00:01:28.760
<v Speaker 2>Well, a process is responsible for some critical things. First,

32
00:01:28.799 --> 00:01:31.599
<v Speaker 2>it gets its own private address space. Think of it

33
00:01:31.680 --> 00:01:34.760
<v Speaker 2>like its own dedicated chunk of memory, its floor plan. Okay.

34
00:01:35.239 --> 00:01:38.200
<v Speaker 2>Then it holds one or more threads, the workers. It

35
00:01:38.239 --> 00:01:40.040
<v Speaker 2>also keeps a handle table.

36
00:01:39.879 --> 00:01:42.120
<v Speaker 1>A handle table like an inventory list short of.

37
00:01:42.200 --> 00:01:44.760
<v Speaker 2>Yeah, yeah, an inventory of all the system resources it's using.

38
00:01:45.000 --> 00:01:48.040
<v Speaker 2>And critically, it's assigned a unique process ID.

39
00:01:48.000 --> 00:01:51.200
<v Speaker 1>Or PID PIDs. Right, we see those in task Manager

40
00:01:51.239 --> 00:01:53.239
<v Speaker 1>all the time. Now, the book says they're unique but

41
00:01:53.319 --> 00:01:56.040
<v Speaker 1>also reusable. How does that work? I sort of assumed

42
00:01:56.040 --> 00:01:58.480
<v Speaker 1>a PID was like permanent.

43
00:01:58.680 --> 00:02:01.120
<v Speaker 2>Yeah, that's common thought. But the key thing is a

44
00:02:01.120 --> 00:02:04.799
<v Speaker 2>PID uniquely identifies a currently running process.

45
00:02:04.519 --> 00:02:05.840
<v Speaker 1>Ah only while it's active.

46
00:02:06.280 --> 00:02:10.080
<v Speaker 2>Exactly as long as that kernel object representing the process exists,

47
00:02:10.479 --> 00:02:14.159
<v Speaker 2>the PID is its tag. But once the process finishes,

48
00:02:14.479 --> 00:02:16.879
<v Speaker 2>poof that kernel object is gone.

49
00:02:16.639 --> 00:02:17.919
<v Speaker 1>And the number can be used again.

50
00:02:17.759 --> 00:02:21.039
<v Speaker 2>Later, right for a completely different new process it's like

51
00:02:21.080 --> 00:02:23.199
<v Speaker 2>reusing raffle ticket numbers for different draws.

52
00:02:23.280 --> 00:02:25.400
<v Speaker 1>That makes total sense, and it's a good reminder. Then,

53
00:02:25.599 --> 00:02:29.599
<v Speaker 1>when we see say multiple Chrome Windows Open or Word instances,

54
00:02:30.240 --> 00:02:33.439
<v Speaker 1>each one is its own distinct process, with its own PID,

55
00:02:33.520 --> 00:02:36.199
<v Speaker 1>its own resources, even though they all started from the

56
00:02:36.240 --> 00:02:37.199
<v Speaker 1>same program file.

57
00:02:37.280 --> 00:02:40.719
<v Speaker 2>Precisely, the dot exc file is the blueprint, but each

58
00:02:40.800 --> 00:02:44.439
<v Speaker 2>running instance gets its own private stuff. Now about that

59
00:02:44.560 --> 00:02:47.520
<v Speaker 2>address space, the private memory. Yeah, the book lays out

60
00:02:47.560 --> 00:02:49.840
<v Speaker 2>some different sizes. It depends on whether it's a sixty

61
00:02:49.840 --> 00:02:51.680
<v Speaker 2>four bit or a thirty two bit process.

62
00:02:51.800 --> 00:02:54.840
<v Speaker 1>Right. For sixty four bit processes on sixty four bit Windows,

63
00:02:55.240 --> 00:02:58.439
<v Speaker 1>we're talking massive amounts of space, right, like eight terabytes

64
00:02:58.520 --> 00:02:59.719
<v Speaker 1>or even one hundred and twenty eight.

65
00:02:59.639 --> 00:03:03.000
<v Speaker 2>Terrabyte, Yes, staggering numbers. Eight terabytes on Windows eight and earlier,

66
00:03:03.000 --> 00:03:05.199
<v Speaker 2>and then one hundred and twenty eight terabytes from Windows

67
00:03:05.280 --> 00:03:07.840
<v Speaker 2>eight point one onwards. It's like having an almost infinite

68
00:03:07.879 --> 00:03:08.560
<v Speaker 2>address book.

69
00:03:08.800 --> 00:03:11.759
<v Speaker 1>Okay, but what about those older thirty two bit programs,

70
00:03:12.000 --> 00:03:14.960
<v Speaker 1>the one still running on our modern sixty four bit systems.

71
00:03:15.120 --> 00:03:18.360
<v Speaker 2>Ah Okay, that's where it gets a bit more nuanced.

72
00:03:19.120 --> 00:03:22.080
<v Speaker 2>By default, a thirty two bit process only gets a

73
00:03:22.120 --> 00:03:23.680
<v Speaker 2>two gigabyte address.

74
00:03:23.360 --> 00:03:24.719
<v Speaker 1>Space only two gigs.

75
00:03:25.080 --> 00:03:28.120
<v Speaker 2>But if the program was built with a special flag,

76
00:03:28.360 --> 00:03:30.240
<v Speaker 2>a setting called large address aware.

77
00:03:30.439 --> 00:03:31.319
<v Speaker 1>Large address aware.

78
00:03:31.439 --> 00:03:34.599
<v Speaker 2>Yeah, if it has that flag, it can actually access

79
00:03:34.680 --> 00:03:37.159
<v Speaker 2>up to four gigabytes on a sixty four bit system.

80
00:03:36.919 --> 00:03:39.439
<v Speaker 1>So it doubles its potential memory pretty much.

81
00:03:39.560 --> 00:03:41.719
<v Speaker 2>Think of the flag as the thirty two bit program

82
00:03:41.840 --> 00:03:44.280
<v Speaker 2>telling the sixty four bit system, Hey, I know how

83
00:03:44.280 --> 00:03:46.039
<v Speaker 2>to handle more memory addresses than usual.

84
00:03:46.159 --> 00:03:49.159
<v Speaker 1>Okay, so that flag signals it's ready for more space. Now.

85
00:03:49.159 --> 00:03:51.719
<v Speaker 1>Another key piece here seems to be these dynamic link

86
00:03:51.800 --> 00:03:54.120
<v Speaker 1>libraries DLLs.

87
00:03:54.199 --> 00:03:58.759
<v Speaker 2>They're everywhere we really are. Dls are essentially packages. They

88
00:03:58.759 --> 00:04:02.840
<v Speaker 2>contain codeta resources things a program might need, and they

89
00:04:02.840 --> 00:04:05.960
<v Speaker 2>get loaded into a process dynamic or dynamically, meaning either

90
00:04:06.000 --> 00:04:08.400
<v Speaker 2>when the process starts up that's called static linking even

91
00:04:08.400 --> 00:04:11.039
<v Speaker 2>though it sounds contradictory, or later on when the process

92
00:04:11.120 --> 00:04:13.639
<v Speaker 2>explicitly asks for it, which is true dynamic linking.

93
00:04:13.800 --> 00:04:16.560
<v Speaker 1>The book mentions you can't just run a DLL directly,

94
00:04:16.759 --> 00:04:19.480
<v Speaker 1>right because they don't have that main entry point like

95
00:04:19.519 --> 00:04:20.319
<v Speaker 1>an executable.

96
00:04:20.560 --> 00:04:24.120
<v Speaker 2>Correct, no main function. But the really interesting part and

97
00:04:24.120 --> 00:04:26.399
<v Speaker 2>a big efficiency thing is the memory sharing.

98
00:04:26.720 --> 00:04:29.240
<v Speaker 1>Ah, yes, tell me about that.

99
00:04:29.439 --> 00:04:32.519
<v Speaker 2>So when multiple processes are using the same DLL, especially

100
00:04:32.600 --> 00:04:35.759
<v Speaker 2>those common Windows DLLs in the system thirty two folder.

101
00:04:35.519 --> 00:04:37.519
<v Speaker 1>Like kernel thirty two dot dll.

102
00:04:37.399 --> 00:04:40.839
<v Speaker 2>Exactly or User thirty two dot DLL. The actual code

103
00:04:40.879 --> 00:04:43.079
<v Speaker 2>from the DLL can be shared in physical.

104
00:04:42.879 --> 00:04:45.519
<v Speaker 1>RAM, so you don't have multiple copies loaded, right.

105
00:04:45.600 --> 00:04:48.600
<v Speaker 2>It avoids wasting precious RAM. It's a huge win.

106
00:04:48.839 --> 00:04:51.920
<v Speaker 1>And these particular DLLs, the subsystem ones, they're the ones

107
00:04:51.959 --> 00:04:54.920
<v Speaker 1>that actually implement the core Windows API. Aren't they the

108
00:04:54.920 --> 00:04:57.639
<v Speaker 1>functions that applications call to talk to the OS.

109
00:04:57.759 --> 00:05:00.759
<v Speaker 2>That's precisely it. They're the gateway for norm user mode

110
00:05:00.759 --> 00:05:04.040
<v Speaker 2>applications to access the underlying power of the Windows kernel.

111
00:05:04.560 --> 00:05:06.360
<v Speaker 2>And this focus is really what the book is all.

112
00:05:06.279 --> 00:05:09.759
<v Speaker 1>About, which leads us nicely into the broader Windows architecture

113
00:05:09.920 --> 00:05:12.519
<v Speaker 1>user mode versus kernel mode.

114
00:05:12.680 --> 00:05:15.839
<v Speaker 2>User mode is where our everyday apps live, Notepad, your

115
00:05:15.920 --> 00:05:20.120
<v Speaker 2>browser games, plus those subsystem DLLs we just talked about,

116
00:05:20.360 --> 00:05:21.759
<v Speaker 2>and also something called win.

117
00:05:21.720 --> 00:05:24.600
<v Speaker 1>RT and kernel mode is the deeper layer, the engine room.

118
00:05:24.720 --> 00:05:27.079
<v Speaker 2>Correct, that's the privileged part of the OS where the

119
00:05:27.079 --> 00:05:29.800
<v Speaker 2>core components run, managing hardware security, that kind of thing.

120
00:05:30.000 --> 00:05:35.120
<v Speaker 1>So user processes, subsystem DLLs and win RT, what's.

121
00:05:34.920 --> 00:05:38.319
<v Speaker 2>That win RT or Windows run Time is a newer

122
00:05:38.360 --> 00:05:41.480
<v Speaker 2>API layer. It came in with Windows eight, mainly for

123
00:05:41.560 --> 00:05:45.000
<v Speaker 2>those Universal Windows Platform apps UWP apps.

124
00:05:44.800 --> 00:05:46.600
<v Speaker 1>The ones from the Microsoft Store mostly.

125
00:05:46.680 --> 00:05:49.600
<v Speaker 2>Yeah, it's built on an older technology called comm Component

126
00:05:49.680 --> 00:05:52.240
<v Speaker 2>Object Model, which is all about software components talking to

127
00:05:52.279 --> 00:05:55.600
<v Speaker 2>each other. And win RT supports multiple programming languages.

128
00:05:55.680 --> 00:05:57.920
<v Speaker 1>Interesting, and it's not just for UWP apps. No.

129
00:05:58.399 --> 00:06:00.839
<v Speaker 2>Recently a subset of win rts is actually available for

130
00:06:00.879 --> 00:06:04.079
<v Speaker 2>traditional desktop applications too. Seems like Microsoft is trying to

131
00:06:04.079 --> 00:06:05.720
<v Speaker 2>bridge the gap between those two worlds.

132
00:06:06.079 --> 00:06:08.920
<v Speaker 1>Makes sense now for anyone listening who's thinking about actually

133
00:06:08.959 --> 00:06:12.639
<v Speaker 1>doing some Windows system programming. The book mentions Duols Visual

134
00:06:12.639 --> 00:06:13.639
<v Speaker 1>Studio primarily.

135
00:06:13.839 --> 00:06:17.759
<v Speaker 2>Yeah, Visual Studio is the main integrated development environment the ID.

136
00:06:18.720 --> 00:06:21.519
<v Speaker 2>The book emphasizes just getting your development set up right

137
00:06:21.560 --> 00:06:22.480
<v Speaker 2>from the start.

138
00:06:22.319 --> 00:06:24.959
<v Speaker 1>And it mentions that even doing a basic Hello World

139
00:06:25.519 --> 00:06:27.639
<v Speaker 1>application can teach you something.

140
00:06:27.759 --> 00:06:30.360
<v Speaker 2>Absolutely. Just compiling it shows you the process and you

141
00:06:30.439 --> 00:06:33.079
<v Speaker 2>might notice subtle differences depending on whether you build it

142
00:06:33.120 --> 00:06:35.680
<v Speaker 2>for a thirty two bit system that's by eighty six

143
00:06:36.199 --> 00:06:38.279
<v Speaker 2>or a sixty four bit system by sixty four.

144
00:06:38.639 --> 00:06:42.959
<v Speaker 1>Okay, And following on from that, character encoding Unicode this

145
00:06:43.040 --> 00:06:43.800
<v Speaker 1>sounds important.

146
00:06:43.959 --> 00:06:46.839
<v Speaker 2>It's crucial, especially for software that needs to work globally.

147
00:06:47.160 --> 00:06:50.240
<v Speaker 2>There's a Unicode setting usually set by default and visual

148
00:06:50.240 --> 00:06:51.040
<v Speaker 2>studio when you.

149
00:06:50.920 --> 00:06:53.839
<v Speaker 1>Compile, and that affects how strings are handled.

150
00:06:53.959 --> 00:06:57.720
<v Speaker 2>Yes, yes, it determines whether a type like lpctstr in

151
00:06:57.759 --> 00:07:01.560
<v Speaker 2>the code represents text using UTFS sixteen, which can handle

152
00:07:01.560 --> 00:07:04.199
<v Speaker 2>pretty much any character from any language, or the much

153
00:07:04.199 --> 00:07:05.519
<v Speaker 2>more limited ASCI standard.

154
00:07:05.759 --> 00:07:09.040
<v Speaker 1>So UTS sixteen is generally preferred definitely, and.

155
00:07:09.040 --> 00:07:11.920
<v Speaker 2>You see this directly in the Windows API functions themselves.

156
00:07:12.240 --> 00:07:15.800
<v Speaker 2>A function like creep mutex, for example, isn't really one function. Well,

157
00:07:15.839 --> 00:07:18.360
<v Speaker 2>it's like a macro. The compiler expands it to either

158
00:07:18.480 --> 00:07:22.560
<v Speaker 2>create mutex WZ the WS for wide characters UTF sixteen,

159
00:07:22.920 --> 00:07:26.959
<v Speaker 2>or create mutexa A for ANSI or ASCI ah.

160
00:07:27.000 --> 00:07:30.879
<v Speaker 1>Okay, So using Unicode means you automatically get the w versions,

161
00:07:31.079 --> 00:07:33.759
<v Speaker 1>which prevents your text getting garbled if it contains non

162
00:07:33.759 --> 00:07:34.639
<v Speaker 1>English characters.

163
00:07:34.680 --> 00:07:37.800
<v Speaker 2>Exactly. It voids data loss and makes your software work

164
00:07:37.879 --> 00:07:41.240
<v Speaker 2>correctly with international text, absolutely vital these days.

165
00:07:41.439 --> 00:07:44.560
<v Speaker 1>The book also flags safer ways to handle strings right

166
00:07:44.680 --> 00:07:47.079
<v Speaker 1>like wccswise.

167
00:07:46.279 --> 00:07:49.959
<v Speaker 2>Yes and functions from the struceay dot EA CHEDDAR. It's

168
00:07:50.040 --> 00:07:52.639
<v Speaker 2>quick reminder that the old C style string functions can

169
00:07:52.680 --> 00:07:55.879
<v Speaker 2>be risky, you know, buffer overflows and security issues. These

170
00:07:55.920 --> 00:07:57.680
<v Speaker 2>newer functions are designed to be much safer.

171
00:07:57.759 --> 00:08:00.000
<v Speaker 1>Good practice to use them and for the code example.

172
00:08:00.120 --> 00:08:03.759
<v Speaker 1>In the book, it mentions helper libraries WISHL and WTL.

173
00:08:03.879 --> 00:08:08.519
<v Speaker 2>Yeah, the Windows Implementation Library WIL and Windows Template Library WTL.

174
00:08:08.879 --> 00:08:12.319
<v Speaker 2>They basically provide convenience C plus plus wrappers around the

175
00:08:12.399 --> 00:08:13.800
<v Speaker 2>raw Windows API.

176
00:08:13.639 --> 00:08:15.639
<v Speaker 1>Makes things less tedious pretty.

177
00:08:15.399 --> 00:08:17.319
<v Speaker 2>Much save if you write in a lot of boilerplate code.

178
00:08:17.360 --> 00:08:20.319
<v Speaker 2>Makes development quicker and less error prone. The book also

179
00:08:20.360 --> 00:08:21.720
<v Speaker 2>touches on Hungarian notation.

180
00:08:22.079 --> 00:08:24.920
<v Speaker 1>Oh yeah, that naming convention like hend for a window

181
00:08:24.959 --> 00:08:26.560
<v Speaker 1>handle exactly.

182
00:08:26.160 --> 00:08:29.439
<v Speaker 2>Or else dir for a pointer to a string. It's

183
00:08:29.439 --> 00:08:32.240
<v Speaker 2>an older style you'll see in the Windows API documentation.

184
00:08:32.360 --> 00:08:35.600
<v Speaker 2>In older code, it embeds the variable type.

185
00:08:35.399 --> 00:08:37.120
<v Speaker 1>In the name, A bit of a historical thing. You

186
00:08:37.120 --> 00:08:38.519
<v Speaker 1>don't have to use it in new code.

187
00:08:38.720 --> 00:08:40.879
<v Speaker 2>No, not really, It's just good to recognize you when

188
00:08:40.919 --> 00:08:46.240
<v Speaker 2>you see it. Okay, So moving on. No system programming

189
00:08:46.240 --> 00:08:49.840
<v Speaker 2>discussion is complete without error handling. What happens when things

190
00:08:49.879 --> 00:08:50.360
<v Speaker 2>go wrong?

191
00:08:51.039 --> 00:08:54.159
<v Speaker 1>Right? How does the Windows API tell you something failed?

192
00:08:54.440 --> 00:08:57.360
<v Speaker 2>There are a few common patterns you'll see. Functions return

193
00:08:57.399 --> 00:09:00.159
<v Speaker 2>a bool. Generally, non zero means success es.

194
00:09:00.519 --> 00:09:03.600
<v Speaker 1>Zero means failure, but don't check for exactly true.

195
00:09:03.799 --> 00:09:05.919
<v Speaker 2>Right The book warms about that success might be one,

196
00:09:06.000 --> 00:09:08.399
<v Speaker 2>or might be two or something else non zero, Just

197
00:09:08.480 --> 00:09:10.399
<v Speaker 2>check if it's zero or not. Think you have types

198
00:09:10.440 --> 00:09:14.799
<v Speaker 2>like l status or long. With those, zero usually means success.

199
00:09:15.159 --> 00:09:18.879
<v Speaker 2>The constant error success is actually zero. Any positive value

200
00:09:18.919 --> 00:09:20.519
<v Speaker 2>indicates a specific.

201
00:09:20.120 --> 00:09:21.679
<v Speaker 1>Error code, an h result.

202
00:09:21.879 --> 00:09:25.159
<v Speaker 2>A result is common two, especially with Calm and Newer

203
00:09:25.200 --> 00:09:30.240
<v Speaker 2>APIs zero or positive generally means success as okay is

204
00:09:30.320 --> 00:09:32.919
<v Speaker 2>zero and negative values signal different errors.

205
00:09:33.480 --> 00:09:35.679
<v Speaker 1>So when a function does fail, how do you find

206
00:09:35.720 --> 00:09:36.200
<v Speaker 1>out why?

207
00:09:37.000 --> 00:09:39.519
<v Speaker 2>The main way is to immediately call to get last

208
00:09:39.519 --> 00:09:43.679
<v Speaker 2>air function immediately Yes, because the next API call might

209
00:09:43.759 --> 00:09:47.279
<v Speaker 2>overwrite the error code and critically get laster gives you

210
00:09:47.320 --> 00:09:49.000
<v Speaker 2>the error code for the current thread.

211
00:09:49.200 --> 00:09:52.559
<v Speaker 1>Ah, So each thread has its own last error value precisely.

212
00:09:52.879 --> 00:09:55.639
<v Speaker 2>If you have multiple threads, you can assume one thread's

213
00:09:55.759 --> 00:09:58.200
<v Speaker 2>error relates to another's failure. It's threads specific.

214
00:09:58.320 --> 00:10:01.080
<v Speaker 1>Got it? Okay? What about finding out Windows version? The

215
00:10:01.080 --> 00:10:03.639
<v Speaker 1>book says the old way get version X is kind

216
00:10:03.639 --> 00:10:04.519
<v Speaker 1>of deprecated now.

217
00:10:04.679 --> 00:10:08.200
<v Speaker 2>Yeah, it's not recommended for various reasons related to compatibility settings.

218
00:10:08.519 --> 00:10:11.080
<v Speaker 2>The modern approach is better, which is there's a header

219
00:10:11.159 --> 00:10:13.279
<v Speaker 2>file version all PRIs dot age with a bunch of

220
00:10:13.279 --> 00:10:16.360
<v Speaker 2>simple functions like is Windows expra, greater, is Windows ten

221
00:10:16.480 --> 00:10:18.399
<v Speaker 2>or greater is when a server and so on.

222
00:10:18.519 --> 00:10:20.120
<v Speaker 1>They just return true or false.

223
00:10:20.200 --> 00:10:23.759
<v Speaker 2>Exactly, much cleaner for most common version checks. Under the

224
00:10:23.799 --> 00:10:27.159
<v Speaker 2>hood they use a more fundamental function called verify version info.

225
00:10:27.799 --> 00:10:29.559
<v Speaker 2>Usually the helpers are all unique.

226
00:10:29.639 --> 00:10:34.080
<v Speaker 1>Okay, nice and simple, right, let's ship gears. Objects and handles.

227
00:10:34.480 --> 00:10:36.759
<v Speaker 1>These sound absolutely central to Windows.

228
00:10:36.840 --> 00:10:40.240
<v Speaker 2>They are fundamental. Handles are everywhere. The book describes them

229
00:10:40.279 --> 00:10:42.720
<v Speaker 2>as basically identifiers for kernel objects.

230
00:10:42.840 --> 00:10:45.240
<v Speaker 1>Kernel objects being what kinds of things.

231
00:10:45.360 --> 00:10:48.279
<v Speaker 2>These are the core resources managed by the Windows kernel itself,

232
00:10:48.960 --> 00:10:53.159
<v Speaker 2>things like files you open, processes that are running threads

233
00:10:53.200 --> 00:10:58.600
<v Speaker 2>doing work, synchronization tools like Mutex's events, all the basic building.

234
00:10:58.240 --> 00:11:01.279
<v Speaker 1>Blocks, okay, And the handle is how our program.

235
00:11:01.080 --> 00:11:03.960
<v Speaker 2>Refers to them, exactly. It's an abstract token, like a

236
00:11:03.960 --> 00:11:06.960
<v Speaker 2>ticket or a claim check. Your user mode program uses

237
00:11:07.000 --> 00:11:09.399
<v Speaker 2>the handle to tell the kernel which object it wants to.

238
00:11:09.320 --> 00:11:12.519
<v Speaker 1>Interact with, so it provides a layer of abstraction and security.

239
00:11:12.720 --> 00:11:15.720
<v Speaker 2>Yes, you don't get direct access to the kernel's internal

240
00:11:15.759 --> 00:11:17.879
<v Speaker 2>data structures. You operate through the handle.

241
00:11:18.039 --> 00:11:21.120
<v Speaker 1>So when we call say, create mutechs to make a

242
00:11:21.159 --> 00:11:23.039
<v Speaker 1>synchronization object.

243
00:11:22.960 --> 00:11:25.799
<v Speaker 2>If it works, you get back a handle value, a

244
00:11:25.919 --> 00:11:29.399
<v Speaker 2>number basically that represents that mutex object living down in

245
00:11:29.399 --> 00:11:32.039
<v Speaker 2>the kernel. And if it fails, the return values usually

246
00:11:32.200 --> 00:11:36.039
<v Speaker 2>zero or null. And then there's open mutex, which is

247
00:11:36.080 --> 00:11:39.799
<v Speaker 2>specifically for getting a handle to a mutex that already

248
00:11:39.799 --> 00:11:40.919
<v Speaker 2>exists and has a name.

249
00:11:41.159 --> 00:11:44.840
<v Speaker 1>Right. Create mutex is interesting because if you give it

250
00:11:44.879 --> 00:11:48.639
<v Speaker 1>a name, it can either create a new named mutex

251
00:11:49.120 --> 00:11:51.200
<v Speaker 1>or it can open an existing one with that name.

252
00:11:51.360 --> 00:11:52.519
<v Speaker 2>How do you know what happened?

253
00:11:53.159 --> 00:11:56.000
<v Speaker 1>Even if create mutex succeeds in opening an existing one,

254
00:11:56.000 --> 00:11:58.799
<v Speaker 1>if you call get last ray after, it will return

255
00:11:58.960 --> 00:11:59.840
<v Speaker 1>error already.

256
00:11:59.519 --> 00:12:02.399
<v Speaker 2>Exists, ah okay, whereas open mutex just fails if the

257
00:12:02.440 --> 00:12:03.320
<v Speaker 2>name mutex.

258
00:12:03.080 --> 00:12:05.279
<v Speaker 1>Isn't there, correct, it won't create one for you.

259
00:12:05.720 --> 00:12:08.320
<v Speaker 2>Now, the book breaks down what's sort of conceptually in

260
00:12:08.360 --> 00:12:11.480
<v Speaker 2>a handle, A pointer to the object and access mask

261
00:12:11.600 --> 00:12:12.279
<v Speaker 2>and flags.

262
00:12:12.559 --> 00:12:15.440
<v Speaker 1>Yeah, that's a simplified view. The access mask is super important.

263
00:12:15.440 --> 00:12:18.399
<v Speaker 1>It defines what operations you're actually allowed to perform using

264
00:12:18.399 --> 00:12:22.279
<v Speaker 1>that specific handle, like permissions exactly. For instance, if you

265
00:12:22.320 --> 00:12:24.679
<v Speaker 1>want to terminate another process. You first need a handle

266
00:12:24.720 --> 00:12:26.799
<v Speaker 1>to it. You get that using open.

267
00:12:26.559 --> 00:12:29.639
<v Speaker 2>Process, but when you call open process you have to

268
00:12:29.720 --> 00:12:34.080
<v Speaker 2>explicitly request the process terminate access right. If the handle

269
00:12:34.120 --> 00:12:36.480
<v Speaker 2>you get back doesn't have that right in its access mask,

270
00:12:36.879 --> 00:12:39.720
<v Speaker 2>then calling terminate process with that handle will just fail.

271
00:12:39.919 --> 00:12:42.720
<v Speaker 1>So the handle encodes the permissions. What about the flags

272
00:12:43.360 --> 00:12:45.639
<v Speaker 1>inheritance Protection from close.

273
00:12:45.600 --> 00:12:49.039
<v Speaker 2>Inheritance means whether a child process created by this process

274
00:12:49.200 --> 00:12:52.799
<v Speaker 2>automatically gets a copy of the handle. Protection from close

275
00:12:53.240 --> 00:12:56.159
<v Speaker 2>handle flag protects from close is a safety feature makes

276
00:12:56.159 --> 00:12:58.840
<v Speaker 2>it harder to accidentally close a really important handle.

277
00:12:58.960 --> 00:13:00.000
<v Speaker 1>Can you change these flags?

278
00:13:00.679 --> 00:13:04.120
<v Speaker 2>Yes, using set handle information and get handle information. And

279
00:13:04.159 --> 00:13:05.600
<v Speaker 2>if you really want to see all the handles a

280
00:13:05.639 --> 00:13:06.399
<v Speaker 2>process has.

281
00:13:06.320 --> 00:13:07.799
<v Speaker 1>Open process explorer.

282
00:13:08.000 --> 00:13:11.960
<v Speaker 2>Process Explorer from cysinternals is the tool. It's invaluable. It

283
00:13:12.000 --> 00:13:15.080
<v Speaker 2>shows the handle value, the type of object, file, thread,

284
00:13:15.200 --> 00:13:17.720
<v Speaker 2>mutex its name if it has one, the object's address

285
00:13:17.759 --> 00:13:20.399
<v Speaker 2>in kernel memory, the raw access mask, and even a

286
00:13:20.440 --> 00:13:23.720
<v Speaker 2>decoded human readable version of the access rights like looking

287
00:13:23.759 --> 00:13:25.360
<v Speaker 2>at the process's internal toolkit.

288
00:13:25.600 --> 00:13:29.080
<v Speaker 1>Definitely a must have tool. Now, managing these handles in code,

289
00:13:29.200 --> 00:13:33.159
<v Speaker 1>especially C plus plus plus A, seems error prone. The

290
00:13:33.200 --> 00:13:35.799
<v Speaker 1>book introduces a smart handle wrapper class.

291
00:13:36.000 --> 00:13:40.120
<v Speaker 2>Yes, it demonstrates a concept called r AII. R AI

292
00:13:40.480 --> 00:13:45.200
<v Speaker 2>resource acquisition is initialization. It basically means the handle resource

293
00:13:45.240 --> 00:13:49.000
<v Speaker 2>is acquired when the C plus plus wrapper object is created,

294
00:13:49.360 --> 00:13:53.240
<v Speaker 2>and crucially, it's automatically released. The handle is closed when

295
00:13:53.240 --> 00:13:56.080
<v Speaker 2>the wrapper object goes out of scope or is destroyed.

296
00:13:56.360 --> 00:14:00.159
<v Speaker 1>Ah, so it cleans up after itself. Prevents handle leaks exactly.

297
00:14:00.240 --> 00:14:03.919
<v Speaker 2>It makes handle management much safer and easier. The example

298
00:14:03.919 --> 00:14:08.080
<v Speaker 2>class also prevents axidel copying of handles, but allows transferring

299
00:14:08.080 --> 00:14:11.600
<v Speaker 2>ownership using something called move semantics. Very useful C plus

300
00:14:11.639 --> 00:14:12.480
<v Speaker 2>plus features neat.

301
00:14:12.559 --> 00:14:16.360
<v Speaker 1>Okay, What about object naming and sessions? Names aren't always

302
00:14:16.399 --> 00:14:17.919
<v Speaker 1>global usually?

303
00:14:17.960 --> 00:14:21.519
<v Speaker 2>Know when your regular user application creates a named object

304
00:14:21.759 --> 00:14:24.399
<v Speaker 2>like a name mutex, that name is typically only visible

305
00:14:24.440 --> 00:14:26.399
<v Speaker 2>within your current user login session.

306
00:14:26.159 --> 00:14:27.960
<v Speaker 1>So another user logged in wouldn't see it.

307
00:14:27.879 --> 00:14:30.600
<v Speaker 2>Correct unless you specifically create it in the global name space.

308
00:14:30.639 --> 00:14:31.159
<v Speaker 1>How do you do that?

309
00:14:31.360 --> 00:14:35.240
<v Speaker 2>You prefix the name with global like global mouse, shared, mutechs.

310
00:14:36.080 --> 00:14:39.600
<v Speaker 2>These live in a special base named objects directory in

311
00:14:39.679 --> 00:14:41.879
<v Speaker 2>the kernel's object manager name space.

312
00:14:42.320 --> 00:14:43.799
<v Speaker 1>Can any application do this?

313
00:14:44.120 --> 00:14:48.120
<v Speaker 2>Well, there's a catch. Modern sandbox apps called app containers

314
00:14:48.200 --> 00:14:50.519
<v Speaker 2>usually don't have the permissions to create objects in the

315
00:14:50.519 --> 00:14:54.080
<v Speaker 2>global name space. It's mainly for services or older desktop

316
00:14:54.080 --> 00:14:55.879
<v Speaker 2>apps needing system wide coordination.

317
00:14:56.279 --> 00:14:59.120
<v Speaker 1>So if you have two separate programs, maybe even started

318
00:14:59.120 --> 00:15:02.639
<v Speaker 1>by different users, they could use these global named objects

319
00:15:02.720 --> 00:15:04.240
<v Speaker 1>to communicate or synchronize.

320
00:15:04.320 --> 00:15:07.519
<v Speaker 2>Yes, that's a primary use case. One process creates the

321
00:15:07.559 --> 00:15:10.679
<v Speaker 2>named object, create mutex with the global name, and another

322
00:15:10.720 --> 00:15:13.559
<v Speaker 2>process can open it using the same name, open mutext,

323
00:15:13.639 --> 00:15:15.919
<v Speaker 2>or even create utechs. Again, the name acts is the

324
00:15:15.919 --> 00:15:16.840
<v Speaker 2>rendezvous point.

325
00:15:17.120 --> 00:15:21.960
<v Speaker 1>Interesting. Another mechanism mentioned is handle duplication using duplicate handle.

326
00:15:22.000 --> 00:15:22.679
<v Speaker 1>What's that about?

327
00:15:22.840 --> 00:15:24.440
<v Speaker 2>This lets you take a handle you have in your

328
00:15:24.480 --> 00:15:27.799
<v Speaker 2>process and create a new handle, potentially in a different

329
00:15:27.799 --> 00:15:31.639
<v Speaker 2>process that refers to the exact same underlying kernel object.

330
00:15:31.679 --> 00:15:32.440
<v Speaker 1>Why would you do that?

331
00:15:32.759 --> 00:15:35.480
<v Speaker 2>A common reason is when a parent process starts a

332
00:15:35.559 --> 00:15:38.720
<v Speaker 2>child process, the parent might want to give the child

333
00:15:38.879 --> 00:15:42.000
<v Speaker 2>access to one of its own open handles, like maybe

334
00:15:42.080 --> 00:15:44.240
<v Speaker 2>it's standard input or output pipe, So.

335
00:15:44.279 --> 00:15:47.399
<v Speaker 1>You duplicate the parent's handle into the child's process space.

336
00:15:47.559 --> 00:15:49.919
<v Speaker 2>Exactly, you need a handle to the target process with

337
00:15:49.960 --> 00:15:52.720
<v Speaker 2>the process you panel permission to do this. You can

338
00:15:52.759 --> 00:15:55.440
<v Speaker 2>even duplicate a handle within the same process if you

339
00:15:55.480 --> 00:15:58.399
<v Speaker 2>need another handle to the same objects, maybe with different

340
00:15:58.440 --> 00:15:59.200
<v Speaker 2>access rights.

341
00:15:59.360 --> 00:16:03.600
<v Speaker 1>Okay. The book then briefly mentions user objects Windows menus

342
00:16:03.639 --> 00:16:07.879
<v Speaker 1>and GDI objects bitmaps, fonts. They're handled a bit differently.

343
00:16:07.960 --> 00:16:11.519
<v Speaker 2>Yeah. User objects like Windows don't use reference counting in

344
00:16:11.559 --> 00:16:14.519
<v Speaker 2>the same way kernel objects do. The first process to

345
00:16:14.559 --> 00:16:18.039
<v Speaker 2>destroy one affects everyone sharing it and their handles their

346
00:16:18.080 --> 00:16:21.240
<v Speaker 2>scope to something called a Windows station, which also manages

347
00:16:21.279 --> 00:16:23.159
<v Speaker 2>things like the clipboard for applications on.

348
00:16:23.120 --> 00:16:25.519
<v Speaker 1>The same desktop, and GDI objects.

349
00:16:25.200 --> 00:16:27.639
<v Speaker 2>Managed by the GDI subsystem, a separate part of Windows.

350
00:16:27.679 --> 00:16:29.879
<v Speaker 1>This is giving us a really solid grounding. Now the

351
00:16:29.919 --> 00:16:33.240
<v Speaker 1>book starts talking about different types of processes. Protective processes

352
00:16:33.320 --> 00:16:35.559
<v Speaker 1>light PPL sounds like a security thing.

353
00:16:35.879 --> 00:16:40.360
<v Speaker 2>It is introduced in Windows eight point one. PPL provides

354
00:16:40.480 --> 00:16:43.879
<v Speaker 2>enhanced protection, making these processes much harder to tamper with

355
00:16:44.080 --> 00:16:48.519
<v Speaker 2>or terminate, even for administrators like antivirus software. That's a

356
00:16:48.559 --> 00:16:52.039
<v Speaker 2>key example. Yes, anti malware services often run as PPLs

357
00:16:52.039 --> 00:16:54.879
<v Speaker 2>to protect themselves from malicious software trying to shut them down.

358
00:16:55.399 --> 00:16:57.360
<v Speaker 2>There are different protection levels within PPL.

359
00:16:57.559 --> 00:17:00.679
<v Speaker 1>Then there are minimal processes Windows ten features. These sound

360
00:17:00.720 --> 00:17:01.559
<v Speaker 1>really stripped down.

361
00:17:01.600 --> 00:17:04.079
<v Speaker 2>They are. They start with a completely empty address space,

362
00:17:04.240 --> 00:17:07.960
<v Speaker 2>no executable no DLLs initially mapped, super lightweight.

363
00:17:08.039 --> 00:17:08.920
<v Speaker 1>What uses them?

364
00:17:09.079 --> 00:17:11.759
<v Speaker 2>The registry process is one example. Another key one is

365
00:17:11.799 --> 00:17:14.480
<v Speaker 2>the memory compression process, which works behind the scenes to

366
00:17:14.519 --> 00:17:16.000
<v Speaker 2>optimize RAM usage.

367
00:17:16.279 --> 00:17:19.359
<v Speaker 1>Memory compression I might not see that in task manager.

368
00:17:19.039 --> 00:17:22.519
<v Speaker 2>Sometimes it is hidden or aggregated, but Process Explorer will

369
00:17:22.559 --> 00:17:26.079
<v Speaker 2>definitely show it. These minimal processes are typically created directly

370
00:17:26.119 --> 00:17:27.160
<v Speaker 2>by the kernel itself.

371
00:17:27.480 --> 00:17:31.079
<v Speaker 1>Fascinating how processes are evolving. The book also clarifies that

372
00:17:31.160 --> 00:17:34.839
<v Speaker 1>PIDs are just special handle values internally, and it covers

373
00:17:34.920 --> 00:17:39.680
<v Speaker 1>the statuses running suspended and not responding. Not responding is

374
00:17:39.759 --> 00:17:41.680
<v Speaker 1>just for GUI apps, right correct.

375
00:17:42.039 --> 00:17:44.960
<v Speaker 2>It happens when the main UI thread gets stuck and

376
00:17:45.000 --> 00:17:48.200
<v Speaker 2>doesn't process window messages for about five seconds or more.

377
00:17:49.160 --> 00:17:52.599
<v Speaker 2>Command line apps never show not responding, okay.

378
00:17:53.279 --> 00:17:56.960
<v Speaker 1>The book then mentions PE files portable executable, the format

379
00:17:57.000 --> 00:17:59.480
<v Speaker 1>for dot exe and dot dll files, and how they

380
00:17:59.519 --> 00:18:01.960
<v Speaker 1>list their dependencies the other DLLs they.

381
00:18:01.880 --> 00:18:04.640
<v Speaker 2>Need right in the import table. And when you launch

382
00:18:04.680 --> 00:18:07.839
<v Speaker 2>a program, the Windows loader has a specific search path

383
00:18:07.880 --> 00:18:10.119
<v Speaker 2>that follows to find those needed DLLs.

384
00:18:10.240 --> 00:18:12.079
<v Speaker 1>What's the order it checks known.

385
00:18:12.000 --> 00:18:16.279
<v Speaker 2>DLLs first, special system ones, then the application's own directory,

386
00:18:16.559 --> 00:18:19.839
<v Speaker 2>then the current directory, then the main system directory System

387
00:18:19.880 --> 00:18:22.960
<v Speaker 2>thirty two or siswas sixty four, and finally all the

388
00:18:22.960 --> 00:18:24.519
<v Speaker 2>directories in the system's path.

389
00:18:24.440 --> 00:18:27.200
<v Speaker 1>Environment variable and if it can't find one, you get.

390
00:18:27.039 --> 00:18:29.720
<v Speaker 2>That dreaded air message box and the process usually fails

391
00:18:29.720 --> 00:18:32.000
<v Speaker 2>to start. Dependency loading is critical.

392
00:18:32.079 --> 00:18:35.240
<v Speaker 1>Then we get to actually starting processes create process. Wow.

393
00:18:35.240 --> 00:18:36.400
<v Speaker 1>Look at all those parameters.

394
00:18:36.440 --> 00:18:39.519
<v Speaker 2>It's like the master control panel for launching applications. You

395
00:18:39.559 --> 00:18:43.319
<v Speaker 2>specify the command line security settings, whether handles are inherited,

396
00:18:43.400 --> 00:18:44.680
<v Speaker 2>creation flags.

397
00:18:44.359 --> 00:18:48.160
<v Speaker 1>Creation flags like creating new console or create suspended exactly.

398
00:18:48.200 --> 00:18:51.039
<v Speaker 2>Also the environment variables, the starting directory, the startup INNEFO

399
00:18:51.119 --> 00:18:53.680
<v Speaker 2>structure which controls the window appearance, and you get back

400
00:18:53.720 --> 00:18:57.079
<v Speaker 2>the handles and IDs in the process information structure. Huge

401
00:18:57.119 --> 00:18:58.240
<v Speaker 2>amount of control.

402
00:18:57.960 --> 00:19:02.119
<v Speaker 1>And process priority classes affecting thread priorities.

403
00:19:01.559 --> 00:19:04.920
<v Speaker 2>Yes, ranging from idle up to real time. Most apps

404
00:19:05.000 --> 00:19:08.519
<v Speaker 2>run at normal setting. Real time usually needs admin rights

405
00:19:08.880 --> 00:19:12.039
<v Speaker 2>because it can really impact system responsiveness if misused.

406
00:19:12.400 --> 00:19:16.839
<v Speaker 1>That startup infos structure too, controls window size position, whether

407
00:19:16.880 --> 00:19:21.559
<v Speaker 1>it's shown, minimize, maximized, even redirecting standard input out pewter.

408
00:19:22.000 --> 00:19:24.359
<v Speaker 2>It's how a parent process shapes the initial state of

409
00:19:24.400 --> 00:19:27.119
<v Speaker 2>its child. The book also gives a nod to a

410
00:19:27.240 --> 00:19:31.240
<v Speaker 2>useful visual studio extension for debugging child processes and reminds

411
00:19:31.319 --> 00:19:35.160
<v Speaker 2>us again you can't just launch UWP apps like normal executables.

412
00:19:34.559 --> 00:19:38.119
<v Speaker 1>Right, They need that special activation mechanism, which brings us

413
00:19:38.160 --> 00:19:40.000
<v Speaker 1>back to PPL again briefly.

414
00:19:39.720 --> 00:19:42.839
<v Speaker 2>Just reinforcing that they have different signer levels, restricting access

415
00:19:42.920 --> 00:19:46.039
<v Speaker 2>even preventing termination by admins. You can see the protection

416
00:19:46.160 --> 00:19:49.119
<v Speaker 2>level and process explorer. The book shows. Trying to launch

417
00:19:49.160 --> 00:19:52.240
<v Speaker 2>calculator fails if you just copy its command line.

418
00:19:51.960 --> 00:19:54.319
<v Speaker 1>Because it's a UWP app needs the proper.

419
00:19:54.079 --> 00:19:58.039
<v Speaker 2>Launch exactly, which involves using those Windows run Time win

420
00:19:58.160 --> 00:20:01.799
<v Speaker 2>rt API. As we mentioned, the I Application Activation Manager

421
00:20:01.839 --> 00:20:05.799
<v Speaker 2>interface is key. Using methods like activate application, you often

422
00:20:05.839 --> 00:20:07.240
<v Speaker 2>need the app's full package name.

423
00:20:07.440 --> 00:20:10.920
<v Speaker 1>Okay. Then a quick mention of minimal and PICO processes. Again,

424
00:20:11.079 --> 00:20:14.519
<v Speaker 1>minimal are kernel created. PICO processes are for things like

425
00:20:14.640 --> 00:20:18.440
<v Speaker 1>the Windows subsystem for Linux WSL translating Linux calls.

426
00:20:18.240 --> 00:20:20.000
<v Speaker 2>Right, but not the main focus here?

427
00:20:20.240 --> 00:20:24.319
<v Speaker 1>Then, how processes end three ways? All threads exit exit

428
00:20:24.359 --> 00:20:27.200
<v Speaker 1>processes call or termain it process from outside.

429
00:20:26.839 --> 00:20:29.640
<v Speaker 2>Pretty much even when your main function returns. In CC

430
00:20:29.759 --> 00:20:33.440
<v Speaker 2>plus plus two, the runtime library calls exit process from

431
00:20:33.480 --> 00:20:37.160
<v Speaker 2>the kernel's view the process ends when its last thread terminates.

432
00:20:36.839 --> 00:20:40.319
<v Speaker 1>And getting info about a running process, get exit code process,

433
00:20:40.480 --> 00:20:43.079
<v Speaker 1>get process times for CPU usage.

434
00:20:42.880 --> 00:20:45.599
<v Speaker 2>Query full process image name. To get the executable path,

435
00:20:45.720 --> 00:20:47.559
<v Speaker 2>you need to allocate a buffer for that one.

436
00:20:47.400 --> 00:20:51.480
<v Speaker 1>And listing all processes. The tool help thirty two snapshot functions.

437
00:20:51.039 --> 00:20:54.039
<v Speaker 2>Create tool help thirty two snapshot process thirty two first,

438
00:20:54.119 --> 00:20:56.720
<v Speaker 2>process thirty two next. That gives you the basics like

439
00:20:56.759 --> 00:20:58.640
<v Speaker 2>PID in name for everything running.

440
00:20:58.839 --> 00:21:02.279
<v Speaker 1>But to do more like terminate or get detailed info,

441
00:21:02.440 --> 00:21:04.079
<v Speaker 1>you need open process first.

442
00:21:04.160 --> 00:21:06.759
<v Speaker 2>Yes, and you need to request the right access permissions.

443
00:21:07.319 --> 00:21:10.519
<v Speaker 2>It might fail for protected system processes. Air five is

444
00:21:10.559 --> 00:21:14.920
<v Speaker 2>access denied. AIR eighty seven often means invalid parameter. Maybe

445
00:21:14.920 --> 00:21:16.480
<v Speaker 2>the PID doesn't exist anymore.

446
00:21:16.640 --> 00:21:18.279
<v Speaker 1>Debug privilege helps.

447
00:21:18.200 --> 00:21:22.119
<v Speaker 2>Sometimes yes, it lets you open more processes running elevated

448
00:21:22.119 --> 00:21:25.880
<v Speaker 2>and visual Studio often grants it implicitly. For even more detail,

449
00:21:26.200 --> 00:21:28.599
<v Speaker 2>there's WTS enumerate process X.

450
00:21:28.720 --> 00:21:30.279
<v Speaker 1>What does that give you things like.

451
00:21:30.240 --> 00:21:34.799
<v Speaker 2>The username, session id, detailed CPU times, handle counts, threadcounts,

452
00:21:35.279 --> 00:21:35.960
<v Speaker 2>or rich review.

453
00:21:36.000 --> 00:21:38.359
<v Speaker 1>Okay, that's a lot on processes. Let's talk about jobs,

454
00:21:38.480 --> 00:21:39.920
<v Speaker 1>grouping processes exactly.

455
00:21:40.079 --> 00:21:42.440
<v Speaker 2>Job objects let you manage a set of processes as

456
00:21:42.480 --> 00:21:45.759
<v Speaker 2>a single unit Process Explorer actually shows if a process

457
00:21:45.839 --> 00:21:47.799
<v Speaker 2>is in a job, how do you use them? Create

458
00:21:47.799 --> 00:21:50.440
<v Speaker 2>one with the separate job object, then add processes to

459
00:21:50.480 --> 00:21:52.880
<v Speaker 2>it using assigned process to job object. You can even

460
00:21:52.880 --> 00:21:54.000
<v Speaker 2>have hierarchies of jobs.

461
00:21:54.039 --> 00:21:55.880
<v Speaker 1>But the real power is restrictions.

462
00:21:55.880 --> 00:21:59.319
<v Speaker 2>Definitely. Using set information job object, you can set limits

463
00:21:59.319 --> 00:22:01.960
<v Speaker 2>on the entire group of processes in the job, things

464
00:22:02.000 --> 00:22:04.200
<v Speaker 2>like total CPU time, total memory commitment.

465
00:22:04.440 --> 00:22:08.279
<v Speaker 1>You can limit UI interactions too, like blocking clipboard access.

466
00:22:08.440 --> 00:22:11.720
<v Speaker 2>Yes, there are UI restrictions you can apply the book

467
00:22:11.759 --> 00:22:15.079
<v Speaker 2>mentions a sample app job monitor that lets you play

468
00:22:15.119 --> 00:22:19.319
<v Speaker 2>with this, like limiting notepad CPU or blocking certain actions.

469
00:22:19.480 --> 00:22:22.640
<v Speaker 1>CPU rate control is newer Windows eight plus.

470
00:22:22.480 --> 00:22:25.440
<v Speaker 2>Reret Right, let's you set a hard percentage limit on

471
00:22:25.480 --> 00:22:28.839
<v Speaker 2>the CPU usage for all processes in the job combined.

472
00:22:29.359 --> 00:22:31.839
<v Speaker 2>Very useful for resource management and sandboxing.

473
00:22:31.920 --> 00:22:35.400
<v Speaker 1>Okay, super useful concept. Now let's dive into threads. We

474
00:22:35.440 --> 00:22:38.440
<v Speaker 1>said these are the actual workers inside a process.

475
00:22:38.599 --> 00:22:41.839
<v Speaker 2>Yes, the independent paths of execution. They allow a single

476
00:22:41.839 --> 00:22:46.240
<v Speaker 2>process to do multiple things concurrently, potentially using multiple CPU cores.

477
00:22:46.440 --> 00:22:48.680
<v Speaker 1>You create them with create thread. Need to give it

478
00:22:48.680 --> 00:22:50.000
<v Speaker 1>a starting function, right.

479
00:22:49.880 --> 00:22:52.480
<v Speaker 2>The threads entry point function plus an optional parameter to

480
00:22:52.519 --> 00:22:55.640
<v Speaker 2>pass to it, stack size settings, creation flags like create

481
00:22:55.720 --> 00:22:57.680
<v Speaker 2>suspended if you don't want to run immediately and you

482
00:22:57.720 --> 00:23:00.119
<v Speaker 2>get back a handle and a thread ID.

483
00:22:59.680 --> 00:23:03.200
<v Speaker 1>Tids are unique system wide like PIDs.

484
00:23:03.480 --> 00:23:07.279
<v Speaker 2>Yes. The book also mentions HyperThreading as MT, where one

485
00:23:07.359 --> 00:23:10.960
<v Speaker 2>physical core looks like multiple logical processors to the OS.

486
00:23:10.720 --> 00:23:14.119
<v Speaker 1>Can boost performance, but potential cache issues can be.

487
00:23:14.319 --> 00:23:17.079
<v Speaker 2>Yeah, threads on the same physical core might compete for cash.

488
00:23:17.319 --> 00:23:20.799
<v Speaker 2>You see logical processors and task manager usually can disable

489
00:23:20.880 --> 00:23:22.359
<v Speaker 2>SMT in the bios if needed.

490
00:23:22.960 --> 00:23:25.680
<v Speaker 1>Now, terminating threads termat thread sounds.

491
00:23:25.400 --> 00:23:29.319
<v Speaker 2>Bad, very bad. Generally it's abrupt. Kills the thread instantly

492
00:23:29.359 --> 00:23:33.319
<v Speaker 2>without cleanup can lead to resource leaks, deadlocks, corrupted data.

493
00:23:33.480 --> 00:23:36.720
<v Speaker 2>Much better to signal the thread to exit gracefully itself. Okay.

494
00:23:36.920 --> 00:23:41.079
<v Speaker 1>Threads have stacks for local variables and handles like processes.

495
00:23:41.119 --> 00:23:44.000
<v Speaker 1>You get one from create thread or open thread right.

496
00:23:44.039 --> 00:23:48.160
<v Speaker 2>Open thread is like open process needs a TID in permissions. Interestingly,

497
00:23:48.200 --> 00:23:50.960
<v Speaker 2>threads don't have a built in name property in the kernel.

498
00:23:50.720 --> 00:23:52.079
<v Speaker 1>But there's a trick for debugging.

499
00:23:52.240 --> 00:23:55.759
<v Speaker 2>Yeah. Using structured exceptions to set a pseudoname helps identify

500
00:23:55.839 --> 00:23:57.119
<v Speaker 2>threads in the debugger, and.

501
00:23:57.119 --> 00:24:00.640
<v Speaker 1>Choosing between c plus plus plus standard library threats and

502
00:24:00.720 --> 00:24:02.000
<v Speaker 1>the Windows API.

503
00:24:01.799 --> 00:24:05.400
<v Speaker 2>Standard librarystd dot thread et cetera. Is cross platform, which

504
00:24:05.400 --> 00:24:08.680
<v Speaker 2>is great, but the Windows API Create thread gives you

505
00:24:08.759 --> 00:24:12.759
<v Speaker 2>much finer control over things like priority, affinity, stack size,

506
00:24:13.119 --> 00:24:14.440
<v Speaker 2>which leads us to scheduling.

507
00:24:14.759 --> 00:24:17.599
<v Speaker 1>Right, How does Windows decide which thread runs when the

508
00:24:17.720 --> 00:24:19.039
<v Speaker 1>scheduler and.

509
00:24:18.920 --> 00:24:22.319
<v Speaker 2>The key thing. Most threads are usually waiting, waiting for IO,

510
00:24:22.480 --> 00:24:25.200
<v Speaker 2>waiting for a lock, et cetera. The scheduler focuses on

511
00:24:25.279 --> 00:24:27.680
<v Speaker 2>threads in the ready state. It's priority based.

512
00:24:27.759 --> 00:24:31.079
<v Speaker 1>Higher priority runs first. Windows has levels from real time

513
00:24:31.200 --> 00:24:31.880
<v Speaker 1>down to idle.

514
00:24:32.039 --> 00:24:36.279
<v Speaker 2>Correct. A thread's actual priority comes from its processes priority

515
00:24:36.319 --> 00:24:39.440
<v Speaker 2>class plus its own relative priority within that.

516
00:24:39.440 --> 00:24:42.079
<v Speaker 1>Process and the quantum the time slice.

517
00:24:42.160 --> 00:24:43.920
<v Speaker 2>Yeah, how long a thread gets to run before the

518
00:24:43.960 --> 00:24:46.880
<v Speaker 2>scheduler might switch. Yeah, It can vary client versus server

519
00:24:46.920 --> 00:24:51.480
<v Speaker 2>tuning and the four ground apps. Threads often get longer quantums.

520
00:24:51.559 --> 00:24:54.559
<v Speaker 2>Quantum stretching for responsiveness.

521
00:24:53.920 --> 00:24:57.359
<v Speaker 1>Can be tweaked in the registry WIN thirty two priority separation.

522
00:24:57.640 --> 00:25:00.359
<v Speaker 2>It can. Yeah. You can also control which ars a

523
00:25:00.400 --> 00:25:03.400
<v Speaker 2>thread runs on process or affinity set thread affinity mask

524
00:25:03.519 --> 00:25:05.960
<v Speaker 2>is the basic way set thread group affinity for systems

525
00:25:05.960 --> 00:25:06.759
<v Speaker 2>with sixty four.

526
00:25:06.640 --> 00:25:10.200
<v Speaker 1>Processors and CPU sets a newer way to group processor Yes.

527
00:25:10.240 --> 00:25:13.680
<v Speaker 2>Windows ten introduce them more abstract way to manage affinity

528
00:25:13.759 --> 00:25:15.000
<v Speaker 2>using functions like set thread.

529
00:25:15.039 --> 00:25:18.599
<v Speaker 1>THEEP sets now priority boosts. This sounds important for keeping

530
00:25:18.640 --> 00:25:19.240
<v Speaker 1>things smooth.

531
00:25:19.599 --> 00:25:23.440
<v Speaker 2>Very the system temporarily boosts a threads priority after certain

532
00:25:23.440 --> 00:25:28.079
<v Speaker 2>events like IO completing or a window needing. Attention prevents

533
00:25:28.079 --> 00:25:29.039
<v Speaker 2>the UI freezing.

534
00:25:29.400 --> 00:25:30.960
<v Speaker 1>It decays back down afterwards.

535
00:25:31.119 --> 00:25:33.559
<v Speaker 2>Yes, after the thread runs for a bit four ground

536
00:25:33.599 --> 00:25:35.480
<v Speaker 2>threads get a bigger boost when they wake up from

537
00:25:35.480 --> 00:25:38.200
<v Speaker 2>a weight. It's all about perceived responsiveness.

538
00:25:38.279 --> 00:25:42.519
<v Speaker 1>Suspending and resuming threads. Suspend thread, ReSm thread Still a

539
00:25:42.519 --> 00:25:43.480
<v Speaker 1>bad idea.

540
00:25:43.359 --> 00:25:46.960
<v Speaker 2>Generally, Yes, very easy to cause deadlocks. Better to use

541
00:25:47.000 --> 00:25:50.799
<v Speaker 2>proper signaling. There are also ways for threads to yield voluntarily.

542
00:25:51.559 --> 00:25:54.039
<v Speaker 2>Sleep baze gives up the rest of its time slice

543
00:25:54.079 --> 00:25:56.519
<v Speaker 2>to another ready thread of the same priority.

544
00:25:56.720 --> 00:25:59.680
<v Speaker 1>Switch to thread yields more aggestively yes to any.

545
00:25:59.519 --> 00:26:03.480
<v Speaker 2>Other ready thread, and sleep infinite just waits forever until

546
00:26:03.480 --> 00:26:04.039
<v Speaker 2>woken up.

547
00:26:04.079 --> 00:26:06.960
<v Speaker 1>It's amazing how much orchestration is going on. Okay, synchronization

548
00:26:07.039 --> 00:26:08.960
<v Speaker 1>within a process. Why do we need it?

549
00:26:09.279 --> 00:26:12.440
<v Speaker 2>Because if multiple threads in the same process access shared

550
00:26:12.519 --> 00:26:17.519
<v Speaker 2>data without coordination, chaos, race conditions, corrupted data, weird bugs.

551
00:26:17.559 --> 00:26:19.680
<v Speaker 1>The simple counter example shows this clearly.

552
00:26:19.839 --> 00:26:23.440
<v Speaker 2>Yeah, the final count is unpredictable for simple increments decrements,

553
00:26:23.480 --> 00:26:25.559
<v Speaker 2>there are interlock operations.

554
00:26:25.240 --> 00:26:28.119
<v Speaker 1>Like interlocked increment. These are atomic, yes.

555
00:26:28.039 --> 00:26:32.119
<v Speaker 2>Hardware guaranteed atomic. The whole read, modify write happens as

556
00:26:32.240 --> 00:26:35.279
<v Speaker 2>one indivisible step, save for simple updates.

557
00:26:35.359 --> 00:26:38.519
<v Speaker 1>For more complex stuff, protecting blocks of code.

558
00:26:38.200 --> 00:26:40.839
<v Speaker 2>Critical sections of the workhorse for that, within a process

559
00:26:41.279 --> 00:26:44.759
<v Speaker 2>initialized critical section X, enter critical section to lock it,

560
00:26:45.039 --> 00:26:48.319
<v Speaker 2>leave critical section to unlock. Only one thread can be

561
00:26:48.440 --> 00:26:52.000
<v Speaker 2>inside the critical section at a time, and delete critical

562
00:26:52.000 --> 00:26:52.720
<v Speaker 2>section when done.

563
00:26:52.799 --> 00:26:56.079
<v Speaker 1>Mutual exclusion. The hashcatch example uses one to protect.

564
00:26:55.759 --> 00:26:59.319
<v Speaker 2>A map exactly std dot unordered map isn't thread safe,

565
00:26:59.519 --> 00:27:02.720
<v Speaker 2>so the critic section ensures safe access from multiple threads.

566
00:27:03.279 --> 00:27:06.559
<v Speaker 2>The book also mentions ETW event tracing.

567
00:27:06.240 --> 00:27:07.799
<v Speaker 1>For Windows for diagnostics.

568
00:27:07.920 --> 00:27:11.319
<v Speaker 2>Yeah, powerful kernel level tracing can see image loads, context switches,

569
00:27:11.400 --> 00:27:13.759
<v Speaker 2>tons of stuff, useful for deep analysis.

570
00:27:13.839 --> 00:27:17.720
<v Speaker 1>Okay, what about SRW locks slim reader.

571
00:27:17.519 --> 00:27:19.599
<v Speaker 2>Writer These are often more efficient if you have lots

572
00:27:19.599 --> 00:27:22.279
<v Speaker 2>of threads reading share data but only occasional rights. They

573
00:27:22.279 --> 00:27:26.039
<v Speaker 2>allow multiple readers or one writer acquires RW lock shared

574
00:27:26.079 --> 00:27:27.960
<v Speaker 2>acquires our wots exclusive, et cetera.

575
00:27:28.119 --> 00:27:30.559
<v Speaker 1>Got it and condition variables used.

576
00:27:30.359 --> 00:27:33.720
<v Speaker 2>With a lock always with a critical section or an

577
00:27:33.799 --> 00:27:37.920
<v Speaker 2>SRW lock. They let threads wait efficiently for some condition

578
00:27:38.039 --> 00:27:42.039
<v Speaker 2>to become true. You call sleep condition variable CS or

579
00:27:42.119 --> 00:27:44.200
<v Speaker 2>sleep condition variable SRW.

580
00:27:44.480 --> 00:27:47.759
<v Speaker 1>This atomically releases the lock while waiting yes.

581
00:27:47.599 --> 00:27:51.200
<v Speaker 2>And reacquires it upon waking. Other threads use weight condition

582
00:27:51.279 --> 00:27:54.599
<v Speaker 2>variable or wake all condition variable to signal crucially, you

583
00:27:54.680 --> 00:27:57.440
<v Speaker 2>must recheck the condition in a loop after waking because

584
00:27:57.480 --> 00:27:58.759
<v Speaker 2>of spurious wakeups.

585
00:27:58.839 --> 00:28:00.920
<v Speaker 1>Spurious wakeups, they can and wake up even if the

586
00:28:00.920 --> 00:28:03.039
<v Speaker 1>condition isn't met sometimes.

587
00:28:02.599 --> 00:28:06.640
<v Speaker 2>Yes, so you always loop while sleep condition variable. The

588
00:28:06.759 --> 00:28:10.240
<v Speaker 2>producer consumer example demonstrates this pattern well with a shared

589
00:28:10.319 --> 00:28:11.000
<v Speaker 2>queue right.

590
00:28:11.319 --> 00:28:14.400
<v Speaker 3>Newer primitives, too, wait and address very efficient way to

591
00:28:14.440 --> 00:28:17.640
<v Speaker 3>wait for a specific memory location to change value, often

592
00:28:17.680 --> 00:28:20.720
<v Speaker 3>without needing a separate lock and synchronization barriers like a

593
00:28:20.759 --> 00:28:24.880
<v Speaker 3>Runov point exactly enter synchronization barrier. Threads wait there until

594
00:28:24.920 --> 00:28:27.440
<v Speaker 3>a specified number of threads arrive. Then they all proceed

595
00:28:27.480 --> 00:28:28.279
<v Speaker 3>together and C.

596
00:28:28.519 --> 00:28:31.799
<v Speaker 1>Plus plus standard library has its own versions std dot

597
00:28:31.880 --> 00:28:34.640
<v Speaker 1>mutex std dot condition variable Yes.

598
00:28:35.240 --> 00:28:38.440
<v Speaker 2>Good for cross platform code, but often less control or

599
00:28:38.480 --> 00:28:43.519
<v Speaker 2>potentially different performance characteristics than the native Windows APIs. Finally,

600
00:28:43.799 --> 00:28:48.240
<v Speaker 2>the basic weight functions wait for single object, wait for multiple.

601
00:28:47.839 --> 00:28:50.799
<v Speaker 1>Objects, need the synchronize right for the object.

602
00:28:50.400 --> 00:28:53.880
<v Speaker 2>Handle yes, and you specify a timeout. They tell you

603
00:28:53.920 --> 00:28:56.599
<v Speaker 2>if the objects signaled, if you kimbed out, or if

604
00:28:56.640 --> 00:28:57.319
<v Speaker 2>there was an error.

605
00:28:57.680 --> 00:29:01.039
<v Speaker 1>Okay, that covers coordinating threads inside one process. What about

606
00:29:01.079 --> 00:29:02.359
<v Speaker 1>between different processes?

607
00:29:02.559 --> 00:29:05.480
<v Speaker 2>For that, you need kernel objects with system wide visibility,

608
00:29:05.880 --> 00:29:07.599
<v Speaker 2>usually achieved using named.

609
00:29:07.359 --> 00:29:09.200
<v Speaker 1>Objects like a named mutex.

610
00:29:09.400 --> 00:29:13.039
<v Speaker 2>Exactly create it with create viewtex and give it a name,

611
00:29:13.160 --> 00:29:17.039
<v Speaker 2>maybe global prefix for system wide. Another process can use

612
00:29:17.079 --> 00:29:19.279
<v Speaker 2>open mutex with the same name to get a handle

613
00:29:19.319 --> 00:29:22.079
<v Speaker 2>to the same mutex. Then they use weight for single

614
00:29:22.079 --> 00:29:23.960
<v Speaker 2>object and release mutechs to coordinate.

615
00:29:24.039 --> 00:29:27.079
<v Speaker 1>Process Explorer can show these named mutexes.

616
00:29:26.559 --> 00:29:30.079
<v Speaker 2>Yep and whether they're currently held. Semaphors work similarly.

617
00:29:30.160 --> 00:29:33.039
<v Speaker 1>Somemophors control access to a limited number of resources.

618
00:29:33.400 --> 00:29:36.920
<v Speaker 2>Right create with create semaphore, give it an initial max

619
00:29:36.920 --> 00:29:40.680
<v Speaker 2>account and a name. Wait for single object, tries to

620
00:29:40.720 --> 00:29:44.400
<v Speaker 2>decrement the count, release semaphor increments it. Good for managing

621
00:29:44.400 --> 00:29:46.319
<v Speaker 2>pools of resources across processes.

622
00:29:46.400 --> 00:29:48.680
<v Speaker 1>Weaightable timers can also be named yes.

623
00:29:48.839 --> 00:29:52.119
<v Speaker 2>Create weightable timer with a name, set weightable timer to

624
00:29:52.119 --> 00:29:56.480
<v Speaker 2>schedule it once or periodically. Other processes can open weightable

625
00:29:56.519 --> 00:29:59.599
<v Speaker 2>timer and wait for single object. Can even trigger APCs

626
00:29:59.799 --> 00:30:00.599
<v Speaker 2>and events.

627
00:30:01.039 --> 00:30:02.640
<v Speaker 1>Named events also possible.

628
00:30:02.839 --> 00:30:05.799
<v Speaker 2>Create event with a name, manual or auto reset, open

629
00:30:05.839 --> 00:30:08.839
<v Speaker 2>event by name, use set event, reset event, wait for

630
00:30:08.880 --> 00:30:11.720
<v Speaker 2>single object. Simple signaling between processes.

631
00:30:11.839 --> 00:30:14.279
<v Speaker 1>Interprocess APCs are less common.

632
00:30:14.039 --> 00:30:16.680
<v Speaker 2>Much less common and trickier named objects the usual way.

633
00:30:17.160 --> 00:30:19.759
<v Speaker 2>The book also mentions weight for impuddle.

634
00:30:19.400 --> 00:30:21.039
<v Speaker 1>Waits for a GUI app to be ready.

635
00:30:21.240 --> 00:30:24.359
<v Speaker 2>Yeah waits until it's finished initializing and is waiting for input.

636
00:30:24.680 --> 00:30:28.440
<v Speaker 2>Useful after create process and signal object and weight atomically

637
00:30:28.440 --> 00:30:32.160
<v Speaker 2>signals one object and weights on another, avoiding certain race conditions.

638
00:30:32.359 --> 00:30:35.799
<v Speaker 1>Lots of tools for interprocess coordination. Let's move to thread pools,

639
00:30:35.960 --> 00:30:37.480
<v Speaker 1>a managed way to handle threads.

640
00:30:37.759 --> 00:30:42.039
<v Speaker 2>Yeah, Windows provides a sophisticated threadpool big advantages, reuses threads,

641
00:30:42.200 --> 00:30:46.200
<v Speaker 2>less overhead, manages resources, better limits concurrency automatically.

642
00:30:46.279 --> 00:30:47.880
<v Speaker 1>What do you use it? Simplest way?

643
00:30:48.200 --> 00:30:51.799
<v Speaker 2>Try submit threadpool callback, give it a function to run,

644
00:30:51.880 --> 00:30:53.920
<v Speaker 2>and the pool schedules it on one of its worker

645
00:30:53.960 --> 00:30:55.200
<v Speaker 2>threads eventually.

646
00:30:54.799 --> 00:30:57.480
<v Speaker 1>That it can do more weight callbacks yes.

647
00:30:57.559 --> 00:30:59.960
<v Speaker 2>Instead of blocking your own thread waiting for an object,

648
00:31:00.519 --> 00:31:04.039
<v Speaker 2>tell the thread pool to weight, create threadpool weight, set

649
00:31:04.039 --> 00:31:07.200
<v Speaker 2>thread pool weight. When the object signals, the pool runs

650
00:31:07.200 --> 00:31:10.839
<v Speaker 2>your callback function. Much more efficient. Timer callbacks too, yep,

651
00:31:11.279 --> 00:31:14.960
<v Speaker 2>create threadpool timer, set thread pool timer schedule callbacks ceriodically

652
00:31:15.119 --> 00:31:16.400
<v Speaker 2>or one shot handled by the.

653
00:31:16.319 --> 00:31:19.119
<v Speaker 1>Pool and io callbacks rising operations.

654
00:31:19.240 --> 00:31:22.160
<v Speaker 2>Right to create thread poolio start thread Polio integrates acinc

655
00:31:22.160 --> 00:31:23.920
<v Speaker 2>iiocompletion with the threadpool.

656
00:31:24.000 --> 00:31:25.599
<v Speaker 1>Can you create your own private pools?

657
00:31:25.839 --> 00:31:32.160
<v Speaker 2>You can create threadpool allows customization minmax threads, stack sizes,

658
00:31:32.440 --> 00:31:35.599
<v Speaker 2>set threadpool thread maximum, et cetera. Need to close thread

659
00:31:35.599 --> 00:31:36.359
<v Speaker 2>pool when done.

660
00:31:36.400 --> 00:31:38.920
<v Speaker 1>Callback environments, cleanup groups.

661
00:31:38.880 --> 00:31:44.359
<v Speaker 2>More advanced features environments, TP callback environ let you set priority, affinity, etc.

662
00:31:44.680 --> 00:31:47.720
<v Speaker 2>For callbacks. Clean up groups help manage the lifetime of

663
00:31:47.759 --> 00:31:49.200
<v Speaker 2>related pool objects. Together.

664
00:31:49.319 --> 00:31:53.960
<v Speaker 1>Thread pools seem very powerful, okay. Advance threading topics. Thread

665
00:31:54.000 --> 00:31:55.599
<v Speaker 1>local storage TLS.

666
00:31:55.720 --> 00:31:58.359
<v Speaker 2>G LS gives each thread its own private coffee of

667
00:31:58.440 --> 00:32:02.279
<v Speaker 2>some data. Use to get an index, then tlset value,

668
00:32:02.400 --> 00:32:05.039
<v Speaker 2>TELS get value, operate on the calling threads specific slot

669
00:32:05.039 --> 00:32:07.880
<v Speaker 2>for that index. No sink needed because it's thread private.

670
00:32:08.079 --> 00:32:10.119
<v Speaker 2>TLS free releases the index.

671
00:32:09.880 --> 00:32:12.519
<v Speaker 1>C plus plus s thread local two Yes t lous.

672
00:32:12.279 --> 00:32:15.240
<v Speaker 2>Pec thread older and thread locals entered. C plus plus

673
00:32:15.319 --> 00:32:17.920
<v Speaker 2>provide language level support for static TLS variables.

674
00:32:18.000 --> 00:32:20.640
<v Speaker 1>How do list threads again, tool help thirty two YEP.

675
00:32:20.480 --> 00:32:22.920
<v Speaker 2>Create tool help thirty two snapshot with th h three

676
00:32:22.960 --> 00:32:25.920
<v Speaker 2>two CSS snap thread then thread thirty two first next

677
00:32:26.039 --> 00:32:28.960
<v Speaker 2>gives TIDPID priority, CPU times.

678
00:32:28.759 --> 00:32:30.599
<v Speaker 1>Cash awareness, False.

679
00:32:30.279 --> 00:32:34.079
<v Speaker 2>Sharing important performance consideration. False sharing is when threads modified

680
00:32:34.119 --> 00:32:36.240
<v Speaker 2>different variables that happen to be in the same CPU

681
00:32:36.279 --> 00:32:40.200
<v Speaker 2>cache line, causing unnecessary cash and validations. Padding data structures

682
00:32:40.240 --> 00:32:40.920
<v Speaker 2>can help avoid it.

683
00:32:40.960 --> 00:32:43.160
<v Speaker 1>Weight change reversal WCT for.

684
00:32:43.240 --> 00:32:47.599
<v Speaker 2>Dead's locks yes an API open thread weightchain, session get

685
00:32:47.599 --> 00:32:50.640
<v Speaker 2>thread weight chain to analyze what locks and objects threads

686
00:32:50.640 --> 00:32:54.359
<v Speaker 2>are waiting on. Can help diagnose deadlocks by showing circular weights.

687
00:32:53.960 --> 00:32:58.000
<v Speaker 1>And the concurrency run time. High level C plus plus library.

688
00:32:57.680 --> 00:33:02.799
<v Speaker 2>For Microsoft Ya provides tasks parallel loops agents simplifies many

689
00:33:02.839 --> 00:33:04.440
<v Speaker 2>common parallel programming patterns.

690
00:33:04.440 --> 00:33:07.400
<v Speaker 1>Okay, nearly there. File and device io Create file and

691
00:33:07.400 --> 00:33:12.480
<v Speaker 1>create file two are key absolutely fundamental for opening creating files, devices, pipes,

692
00:33:12.640 --> 00:33:16.759
<v Speaker 1>tons of parameters, path access rights, read write, share mode

693
00:33:17.079 --> 00:33:20.920
<v Speaker 1>creation disposition like creating new open existing flags and attributes.

694
00:33:21.079 --> 00:33:23.880
<v Speaker 2>File flag overlapped is crucial for ACNC io.

695
00:33:23.839 --> 00:33:26.880
<v Speaker 1>Yes, and paths can include for devices or things like

696
00:33:26.920 --> 00:33:29.839
<v Speaker 1>symbolic links. Drive letters themselves are often similark.

697
00:33:29.480 --> 00:33:31.400
<v Speaker 2>Getting file info size.

698
00:33:31.079 --> 00:33:33.920
<v Speaker 1>Attributes, get file size x sixty four bit size, get

699
00:33:33.960 --> 00:33:37.240
<v Speaker 1>file attributesx, get file information by handle for more details,

700
00:33:37.400 --> 00:33:40.839
<v Speaker 1>set file information by handle. Can even modify some things reading.

701
00:33:40.559 --> 00:33:43.680
<v Speaker 2>And writing read file, write file, sync or async both.

702
00:33:44.519 --> 00:33:47.920
<v Speaker 2>ACNC requires the file flag overlapped flag during create file

703
00:33:48.160 --> 00:33:51.599
<v Speaker 2>and using an overlap structure. APCs are one way to

704
00:33:51.640 --> 00:33:56.799
<v Speaker 2>handle ACNC completion, but iocompletion ports IOCP are more scalable.

705
00:33:57.119 --> 00:34:01.240
<v Speaker 1>IOCP involves create iocompletion port associating hands than worker threads,

706
00:34:01.279 --> 00:34:03.319
<v Speaker 1>calling get cubed completion status.

707
00:34:03.000 --> 00:34:07.440
<v Speaker 2>Exactly highly efficient for servers handling many concurrent acinc io operations.

708
00:34:08.280 --> 00:34:11.760
<v Speaker 2>Threadpool io create thread poolio is a simpler wrapper around

709
00:34:11.760 --> 00:34:12.719
<v Speaker 2>similar concepts.

710
00:34:12.719 --> 00:34:15.800
<v Speaker 1>Canceling IO, conciliox yes, cancilo.

711
00:34:15.480 --> 00:34:19.199
<v Speaker 2>X for ACNC cancel synchronusio exist but isn't guaranteed to work.

712
00:34:19.320 --> 00:34:23.039
<v Speaker 1>Device io uses create file with device paths like physical

713
00:34:23.119 --> 00:34:24.199
<v Speaker 1>drive YEP.

714
00:34:24.079 --> 00:34:26.800
<v Speaker 2>Then device iiO control since commands directly to the driver

715
00:34:26.960 --> 00:34:27.920
<v Speaker 2>using control codes.

716
00:34:28.079 --> 00:34:30.880
<v Speaker 1>Finding devices, the set up DAPI right.

717
00:34:30.719 --> 00:34:33.960
<v Speaker 2>Set of digit class, DEEVS setup dynam device info. Setup

718
00:34:34.000 --> 00:34:37.079
<v Speaker 2>DIET Device interface detail lets you find devices by type

719
00:34:37.079 --> 00:34:37.880
<v Speaker 2>and get their paths.

720
00:34:38.000 --> 00:34:41.199
<v Speaker 1>Interprocess communication again pipes anonymous and named.

721
00:34:41.440 --> 00:34:44.400
<v Speaker 2>Create pipe for simple parent child anonymous pipes, create name

722
00:34:44.480 --> 00:34:47.480
<v Speaker 2>pipe for more powerful. Name pipes can be duplex workover network.

723
00:34:47.639 --> 00:34:49.039
<v Speaker 2>Clients connect using create.

724
00:34:48.840 --> 00:34:50.719
<v Speaker 1>File mail slots one way.

725
00:34:50.800 --> 00:34:54.599
<v Speaker 2>Yes, connectionless, create mail slot for server, Create fil rite

726
00:34:54.599 --> 00:34:57.760
<v Speaker 2>file for client Yeah less common now also file finding

727
00:34:58.199 --> 00:35:00.480
<v Speaker 2>find first file etcter and system info.

728
00:35:00.639 --> 00:35:04.880
<v Speaker 1>Get system info okay, last major topic. Memory management fundamentals

729
00:35:05.320 --> 00:35:06.480
<v Speaker 1>Virtual memory.

730
00:35:06.239 --> 00:35:09.440
<v Speaker 2>The big abstraction. Each process gets its own private address

731
00:35:09.440 --> 00:35:12.119
<v Speaker 2>s base managed by the virtual memory and manager. VMM

732
00:35:12.639 --> 00:35:15.119
<v Speaker 2>uses paging to swap memory between RAM and the disc

733
00:35:15.199 --> 00:35:15.760
<v Speaker 2>page file.

734
00:35:16.159 --> 00:35:20.119
<v Speaker 1>Memory states free, reserved, committed, free is unused.

735
00:35:20.199 --> 00:35:24.119
<v Speaker 2>Reserved allocates address range but no storage. Committed allocates storage

736
00:35:24.280 --> 00:35:26.800
<v Speaker 2>RAM or page file commit, charge and task Manager is

737
00:35:26.840 --> 00:35:28.559
<v Speaker 2>the system wide total committed.

738
00:35:28.199 --> 00:35:31.320
<v Speaker 1>Memory for a process commits size, private bytes is key,

739
00:35:31.639 --> 00:35:33.920
<v Speaker 1>working set is RAM usage generally.

740
00:35:33.679 --> 00:35:36.960
<v Speaker 2>Yes, virtual size includes reserved, working set is physical. RAM.

741
00:35:37.199 --> 00:35:38.800
<v Speaker 2>Process Explorer shows these well.

742
00:35:38.960 --> 00:35:42.679
<v Speaker 1>Process memory map shows layout code, DLL stack keep, Get

743
00:35:42.719 --> 00:35:45.400
<v Speaker 1>process memory info, gives detailed stats.

744
00:35:45.039 --> 00:35:48.360
<v Speaker 2>Page faults working set size, pool usage, page file usage,

745
00:35:48.559 --> 00:35:51.639
<v Speaker 2>and page protection. Read write execute is critical set by

746
00:35:51.719 --> 00:35:55.119
<v Speaker 2>virtual ALC, change by virtual protect access violation if you break.

747
00:35:54.920 --> 00:35:58.239
<v Speaker 1>The rules virtual virtual query X lets you walk the

748
00:35:58.280 --> 00:35:59.039
<v Speaker 1>address space.

749
00:35:59.239 --> 00:36:04.360
<v Speaker 2>Yes, gives in memory based information about regions, base size,

750
00:36:04.519 --> 00:36:08.000
<v Speaker 2>state protection type. Let's you see the map programmatically.

751
00:36:08.079 --> 00:36:11.199
<v Speaker 1>And finally, WAWW sixty four for running thirty two bit

752
00:36:11.239 --> 00:36:15.079
<v Speaker 1>apps on sixty four bit Windows file system redirection system

753
00:36:15.119 --> 00:36:17.159
<v Speaker 1>thirty two versus siswell sixty four.

754
00:36:17.079 --> 00:36:20.719
<v Speaker 2>Exactly the emulation layer that makes it mostly seamless. Wow

755
00:36:20.800 --> 00:36:24.360
<v Speaker 2>sixty four disabled whole sixty four f's redirection can turn

756
00:36:24.400 --> 00:36:26.519
<v Speaker 2>off the file redirection temporarily if needed.

757
00:36:26.559 --> 00:36:30.000
<v Speaker 1>Wow. Okay, that was genuinely a deep dive. We covered

758
00:36:30.039 --> 00:36:31.119
<v Speaker 1>so much ground.

759
00:36:30.840 --> 00:36:34.360
<v Speaker 2>We really did, from processes as containers, threads as the workers,

760
00:36:34.599 --> 00:36:37.039
<v Speaker 2>through handles, synchronization nightmares huh.

761
00:36:37.280 --> 00:36:39.039
<v Speaker 1>And io memory basics.

762
00:36:39.039 --> 00:36:40.639
<v Speaker 2>It's a lot, it is. You know, one thing that

763
00:36:40.639 --> 00:36:42.840
<v Speaker 2>always strikes me is that PID thing just being a

764
00:36:42.840 --> 00:36:47.000
<v Speaker 2>handle value and those minimal processes completely empty to start with.

765
00:36:47.039 --> 00:36:47.679
<v Speaker 2>That's pretty wild.

766
00:36:47.800 --> 00:36:50.199
<v Speaker 1>Yeah. And the whole dance of threads scheduling the boosts.

767
00:36:50.239 --> 00:36:52.960
<v Speaker 1>It really helps understand why things feel responsive for sometimes

768
00:36:52.960 --> 00:36:55.360
<v Speaker 1>why they don't and for you listening, even if you're

769
00:36:55.400 --> 00:36:58.000
<v Speaker 1>not writing this kind of low level code. I think

770
00:36:58.159 --> 00:37:00.800
<v Speaker 1>understanding these concepts gives you a much better feel for

771
00:37:00.880 --> 00:37:03.079
<v Speaker 1>what your computer is actually doing under the hood.

772
00:37:03.199 --> 00:37:06.440
<v Speaker 2>It definitely demystifies some of it takes away the magic feeling.

773
00:37:06.719 --> 00:37:11.920
<v Speaker 1>So thinking about all this complexity. It's what makes Windows powerful, right,

774
00:37:12.400 --> 00:37:15.119
<v Speaker 1>but it also feels like there are so many moving parts.

775
00:37:15.360 --> 00:37:19.360
<v Speaker 2>Absolutely, it's this incredible layering of abstractions and mechanisms built

776
00:37:19.440 --> 00:37:23.920
<v Speaker 2>up over decades. It enables amazing things. But yeah, complexity

777
00:37:23.960 --> 00:37:25.000
<v Speaker 2>can also mean fragility.

778
00:37:25.039 --> 00:37:28.519
<v Speaker 1>Sometimes it makes you wonder how does this foundation contribute

779
00:37:28.559 --> 00:37:32.280
<v Speaker 1>to both stability and the occasional crash, And what other

780
00:37:32.360 --> 00:37:35.199
<v Speaker 1>deep system areas might be interesting to explore next time,

781
00:37:35.320 --> 00:37:38.440
<v Speaker 1>maybe digging into how memory actually gets allocated or how

782
00:37:38.519 --> 00:37:39.239
<v Speaker 1>drivers work.

783
00:37:39.480 --> 00:37:42.679
<v Speaker 2>Definitely food for thought, something to mull over until our

784
00:37:42.719 --> 00:37:44.519
<v Speaker 2>next deep dive. Thanks for joining us.
