The errata list is a list of errors and their corrections that were found after the product was released. If the error was corrected in a later version or reprint the date of the correction will be displayed in the column titled "Date Corrected".
The following errata were submitted by our customers and approved as valid errors by the author or editor.
Version |
Location |
Description |
Submitted By |
Date submitted |
Date corrected |
Printed |
Page xiii
next-to-last para., last line: changed "Mfc" to "Mcl" |
|
Anonymous |
|
Apr 01, 1998 |
Printed |
Page 3
The second line of the third bullet did read: "...spends a large |
faction..."
Now reads:
"...spends a large fraction..."
|
Anonymous |
|
Jun 01, 2000 |
Printed |
Page 7
The last line of code on the page did read: "PGADGET PFreeGadget = |
gpFreeGadgetss;"
Now reads:
"PGADGET PFreeGadget ="gpFreeGadgets;"
|
Anonymous |
|
Jun 01, 2000 |
Printed |
Page 33
last bullet, line -4: changed "objet" to "object" |
|
Anonymous |
|
Apr 01, 1998 |
Printed |
Page 47-48
The following statement in the last paragarph of this page was |
incorrect:
"This technique [using CREATE_SUSPENDED with CreateProcess] is
generally used by a parent process that wants to assign the STDIN
or STDOUT handles for the child process to refer to a pipe or other
kernel object. By creating the process so that the primary thread
is initially suspended, the parent process can safely use the
SetStdHandle function to redirect one or more of the standard input
or output handles for the child process before the primary thread
has a chance to execute."
In fact, by the time the parent process returns from calling CreateProcess,
the handle table for the child process is completely initialized, including
those entries used for stdin, stdout, and stderr. To modify the STD handle(s)
of a child process, the parent process must replace it's own STD handle(s)
using SetStdHandle, launch the child process using CreateProcess and the
bInheritHandles parameter set to TRUE, then restore the parent STD handles
to their original state. Alternatively, the STARTUPINFO field members
hStdInput, hStdOutput, and/or hStdError may be used to setup the STD handles
of a child process that is being started.
This sentence and every sentence that follows to the end of the paragraph
has been deleted. So the last sentence in this paragraph is now "In this
case, the primary thread for a process will not begin exeuting the main or
WinMain function until the parent process has called the ResumeThread
function."
|
Anonymous |
|
Jan 01, 2000 |
Printed |
Page 75
last item in last table: changed "object" to "objects" |
|
Anonymous |
|
Apr 01, 1998 |
Printed |
Page 84
next-to-last para: changed the last 5 lines, starting with "If a |
thread owning a mutex exits..." and continuing on to the end of the
paragraph, to the following:
Note that if a thread owning a mutex exits or is terminated before
releasing the mutex, one of the threads waiting for ownership of that
mutex will return from its wait function with a failure code of
WAIT_ABANDONED_0, or a value between WAIT_ABANDONED_0 and
(WAIT_ABANDONED_0 + nCount-1) for the multiple object wait
functions. That thread is now the owner of the mutex, and must use
ReleaseMutex just as if a return value of WAIT_OBJECT_0 or
(WAIT_OBJECT_0 + nCount-1) had been returned. This means that both the
WaitSucceeded and WaitAbandoned functions presented earlier indicate
you own the mutex and need to release it. Most of the time, an
abandoned mutex is a sign of a bug in the logic of a thread somewhere
and should be asserted so that you can track down the problem as early
as possible.
where the WAIT_ABANDONED items are in CW, "nCount" is in italic CW
both times it appears, and the function names are in Roman itals.
|
Anonymous |
|
Apr 01, 1998 |
Printed |
Page 84
|
The third sentence of the second full paragraph on the page now reads:
"If a thread owning a mutex exits or is terminated before releasing the mutex,
one thread waiting for ownership of that mutex will return from its respective
wait function with a failure code of WAIT_ABANDONED_0, or a value between
WAIT_ABANDONED_0 and (WAIT_ABANDONED_0 + nCount - 1) for the multiple object
wait functions."
|
Anonymous |
|
Jun 01, 2000 |
Printed |
Page 85
reprinted for pagebreak |
|
Anonymous |
|
Apr 01, 1998 |
Printed |
Page 110
Removed the * footnote from the last paragraph on page 110 that refers |
the reader to the editorial note (the sentence that begins "In fact, since
the MapViewOfFile function increases the usage counts..."). No text has been
changed in the paragraph preceding the code listing - just the footnote has
been removed.
After the listing on page 110 (which is fine as-is), this new paragraph has
been added:
"While closing the file mapping handle immediately after calling
MapViewOfFile is valid when performing memory-mapped file I/O, this
technique should not be used when using a file mapping object for
shared memory purposes. In the shared-memory scenario, two or more
processes have agreed on the name for the mapping object. If one
application closes the mapping object after calling MapViewOfFile
before the cooperating application has a chance to call
CreateFileMapping or OpenFileMapping, the named mapping object may
no longer exist (or at least, may no longer be identifiable by the
agreed upon name), and the two applications will not achieve shared
memory as desired. For this reason, the mapping object handle
should not be closed until you no longer have any need to use the
shared memory."
|
Anonymous |
|
Jan 01, 2000 |
Printed |
Page 111-112
Replaced the code listing in Example 5-1 (ShareStr.c) with the |
following code. This source, which demonstrates using a mapping object for
shared memory, follows the recommendation made in the new paragraph on page
110.
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#define MAX_STRING_SIZE 256
#define FILE_MAPPING_NAME __TEXT("ShareStrSharedMemory")
#define INITIAL_STRING __TEXT("(nothing yet)")
int main( int argc, char *argv[]) {
HANDLE hMapping;
LPTSTR lpSharedString;
TCHAR szLocalString[MAX_STRING_SIZE];
BOOL bCreated;
// create a named file mapping as shared memory...
hMapping = CreateFileMapping( (HANDLE) 0xFFFFFFFF, NULL, PAGE_READWRITE, 0,
MAX_STRING_SIZE, FILE_MAPPING_NAME);
if (hMapping != NULL) {
if (GetLastError() == ERROR_ALREADY_EXISTS) {
bCreated = FALSE;
printf("Opened preexisting file mapping.
");
}
else {
bCreated = TRUE;
printf("Created file mapping.
");
}
}
else {
printf("Unable to create file mapping, exiting!
");
exit(-1);
}
// map the memory into this process...
lpSharedString = (LPTSTR) MapViewOfFile( hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if (lpSharedString == NULL) {
printf("Unable to map into memory, exiting!
");
exit(-1);
}
// initialize the string if necessary...
if (bCreated)
_tcscpy( lpSharedString, INITIAL_STRING);
while (TRUE) {
printf( "Type a string to share, [Enter] to display current string, or "quit":
");
// input string...
_getts( szLocalString);
if (_tcscmp( szLocalString, __TEXT("quit")) == 0) {
// quit...
break;
}
else if (szLocalString[0] == __TEXT(' |