How do I link against the ucrt library in Visual Studio 2019? - c

I am trying to understand how the linking process works for C programs in VS2019. According to Microsoft Docs, I need to pass the \MD option to link against ucrt.lib.
I wrote an empty main function and compiled+linked it to Sample.exe under two different configurations. In the default Debug configuration, the final binary produces the following output on running dumpbin /imports Sample.exe:
VCRUNTIME140D.dll
41B098 Import Address Table
41B2A4 Import Name Table
0 time date stamp
0 Index of first forwarder reference
2E __vcrt_GetModuleFileNameW
35 _except_handler4_common
48 memset
1D __current_exception_context
1C __current_exception
2F __vcrt_GetModuleHandleW
31 __vcrt_LoadLibraryExW
25 __std_type_info_destroy_list
ucrtbased.dll
41B0E8 Import Address Table
41B2F4 Import Name Table
0 time date stamp
0 Index of first forwarder reference
2EE _seh_filter_dll
545 strcat_s
2E2 _register_onexit_function
10C _execute_onexit_table
E8 _crt_atexit
E7 _crt_at_quick_exit
E0 _controlfp_s
566 terminate
3C9 _wmakepath_s
3E5 _wsplitpath_s
57F wcscpy_s
8E __stdio_common_vsprintf_s
549 strcpy_s
73 __p__commode
2FA _set_new_mode
DB _configthreadlocale
2E3 _register_thread_local_exe_atexit_callback
C5 _c_exit
CA _cexit
70 __p___argv
6F __p___argc
2F7 _set_fmode
111 _exit
476 exit
19A _initterm_e
199 _initterm
162 _get_initial_narrow_environment
196 _initialize_narrow_environment
DC _configure_narrow_argv
81 __setusermatherr
2F2 _set_app_type
2EF _seh_filter_exe
15 _CrtDbgReportW
14 _CrtDbgReport
197 _initialize_onexit_table
KERNEL32.dll
41B000 Import Address Table
41B20C Import Name Table
0 time date stamp
0 Index of first forwarder reference
345 HeapAlloc
37F IsDebuggerPresent
462 RaiseException
3EF MultiByteToWideChar
5FE WideCharToMultiByte
44D QueryPerformanceCounter
218 GetCurrentProcessId
2E9 GetSystemTimeAsFileTime
58C TerminateProcess
217 GetCurrentProcess
2AE GetProcAddress
1AB FreeLibrary
5CE VirtualQuery
2B4 GetProcessHeap
349 HeapFree
21C GetCurrentThreadId
261 GetLastError
278 GetModuleHandleW
386 IsProcessorFeaturePresent
2D0 GetStartupInfoW
56D SetUnhandledExceptionFilter
5AD UnhandledExceptionFilter
363 InitializeSListHead
Whereas, under the Release configuration, I am getting this:
VCRUNTIME140.dll
402034 Import Address Table
402608 Import Name Table
0 time date stamp
0 Index of first forwarder reference
48 memset
1D __current_exception_context
1C __current_exception
35 _except_handler4_common
KERNEL32.dll
402000 Import Address Table
4025D4 Import Name Table
0 time date stamp
0 Index of first forwarder reference
386 IsProcessorFeaturePresent
37F IsDebuggerPresent
363 InitializeSListHead
2E9 GetSystemTimeAsFileTime
21C GetCurrentThreadId
5AD UnhandledExceptionFilter
56D SetUnhandledExceptionFilter
217 GetCurrentProcess
58C TerminateProcess
218 GetCurrentProcessId
44D QueryPerformanceCounter
278 GetModuleHandleW
api-ms-win-crt-runtime-l1-1-0.dll
402060 Import Address Table
402634 Import Name Table
0 time date stamp
0 Index of first forwarder reference
44 _set_app_type
39 _initterm_e
58 exit
25 _exit
35 _initialize_narrow_environment
5 __p___argc
6 __p___argv
17 _cexit
16 _c_exit
3F _register_thread_local_exe_atexit_callback
19 _configure_narrow_argv
42 _seh_filter_exe
2A _get_initial_narrow_environment
36 _initialize_onexit_table
3E _register_onexit_function
1F _crt_atexit
1D _controlfp_s
6A terminate
38 _initterm
api-ms-win-crt-math-l1-1-0.dll
402058 Import Address Table
40262C Import Name Table
0 time date stamp
0 Index of first forwarder reference
2E __setusermatherr
api-ms-win-crt-stdio-l1-1-0.dll
4020B0 Import Address Table
402684 Import Name Table
0 time date stamp
0 Index of first forwarder reference
54 _set_fmode
1 __p__commode
api-ms-win-crt-locale-l1-1-0.dll
402050 Import Address Table
402624 Import Name Table
0 time date stamp
0 Index of first forwarder reference
8 _configthreadlocale
api-ms-win-crt-heap-l1-1-0.dll
402048 Import Address Table
40261C Import Name Table
0 time date stamp
0 Index of first forwarder reference
16 _set_new_mode
The link on top talks about how two different versions of the DLLs are used for Release and Debug configurations but here, I am linking to two different sets of DLLs. Why is this happening? The docs say that ucrt.dll is sufficient for the Standard C library functions. How do I just link to that?
Also, why do I require VCRUNTIME DLL when I am not using any C++?

Related

Possible (invisible) characters in text pasted from Excel or XML to a TSQL query

My ASP.Net application receives an uploaded Excel file, then converts to XML to pass as a stored procedure parameter for processing. This file contains lots of entries that are text-matched to find the corresponding value.
Today (after working perfectly for years) three seemingly identical values caused mixed results on the text match. I can only illustrate with an example:
The first value is the original value within Excel (copied from the
spreadsheet).
The second value is that which the web application
saves to XML, and is the raw value taken from the profiler showing
the parameter values
The third value is that which currently exists
in the table
The code is pasted from SSMS:
SELECT SkillGroupTitle FROM tbl_SkillGroups WHERE SkillGroupTitle = N'Quality Assurance Instruction (QAI)'; -- pasted from Excel
SELECT SkillGroupTitle FROM tbl_SkillGroups WHERE SkillGroupTitle = N'Quality Assurance Instruction (QAI)'; -- pasted from xml
SELECT SkillGroupTitle FROM tbl_SkillGroups WHERE SkillGroupTitle = N'Quality Assurance Instruction (QAI)'; -- pasted from SQL table (existing value)
Can somebody please advise what is happening here? All values appear identical visually, but there's clearly something different within the inbound values from Excel.
Update
Pasting the two values into a hex converter, there are indeed three differences.
Excel data:
51 75 61 6c 69 74 79 a0 41 73 73 75 72 61 6e 63 65 a0 49 6e 73 74 72 75 63 74 69 6f 6e 20 28 51 41 49 29 0a
-- -- --
SQL data:
51 75 61 6c 69 74 79 20 41 73 73 75 72 61 6e 63 65 20 49 6e 73 74 72 75 63 74 69 6f 6e 20 28 51 41 49 29
Can anyone shed any light here please?
Updated
First, to identify hidden characters causing strings not to be equal you can leverage ngrams8k like this:
WITH tbl_SkillGroups(dSource, SkillGroupTitle) AS
(
SELECT 'Excel', N'Quality Assurance Instruction (QAI)' -- pasted from Excel
UNION ALL
SELECT 'XML', N'Quality Assurance Instruction (QAI)'+CHAR(10) -- pasted from xml
UNION ALL
SELECT 'SQL', N'Quality Assurance Instruction (QAI)'+CHAR(13) -- pasted from SQL table (existing value)
)
SELECT
[Source] = ts.dSource,
Position = ng.Position,
Token = ng.Token,
asciiValue = ASCII(ng.Token)
FROM tbl_SkillGroups AS ts
CROSS APPLY samd.ngrams8k(ts.SkillGroupTitle,1) AS ng
--WHERE ng.Position > 32 -- Zoom into the last few characters
Returns:
Source Position Token asciiValue
------ --------- ------- -----------
Excel 33 A 65
Excel 34 I 73
Excel 35 ) 41 -- Only 35 characters
XML 33 A 65
XML 34 I 73
XML 35 ) 41
XML 36 10 -- 36th character is a CHAR(10) (Looks like a space)
SQL 33 A 65
SQL 34 I 73
SQL 35 ) 41
SQL 36 13 -- 36th character is a CHAR(13) (Also looks like a space)
NEXT, to clean hidden characters from your inputs you can use PatReplace8k.
WITH tbl_SkillGroups(dSource, SkillGroupTitle) AS
(
SELECT 'Excel', N'Quality Assurance Instruction (QAI)' -- pasted from Excel
UNION ALL
SELECT 'XML', N'Quality Assurance Instruction (QAI)'+CHAR(10) -- pasted from xml
UNION ALL
SELECT 'SQL', N'Quality Assurance Instruction (QAI)'+CHAR(13) -- pasted from SQL table (existing value)
)
SELECT SkillGroupTitle
FROM tbl_SkillGroups as ts
CROSS APPLY PatReplace8K(ts.Skillgrouptitle,'[^a-zA-Z ()]','') as pr
WHERE SkillGroupTitle = pr.NewString
Returns:
SkillGroupTitle
------------------------------------
Quality Assurance Instruction (QAI)
Quality Assurance Instruction (QAI)
Quality Assurance Instruction (QAI)
Here, PatReplace8k would remove any characters that didn't match the pattern (letters, spaces and parentheses) thus making these three values equal.

Old school "Commodore 64" BASIC - Peek/Poke commands; is there an equivalent in BATCH form?

I'm an 'Old Timer' that learned to program on a Commodore 64 with a cassette drive (not a disk drive) for storing data. Oh the joy!
I am wondering if there is an equivalent way to perform Peek and Poke commands in a .bat file. Is it even possible anymore to check a specific address the way it worked in BASIC language?
Can a batch file locate the address of something like whether or not the 'y' key has been pressed and can it also set the value of that address to indicate that key was pressed?
It used to be something like PEEK(64324) would return the value of that location. Likewise; POKE(64324) would set the value at that location.
I could run a loop that basically waited for a keyboard input and if it recieved the correect trigger at that address it would perform a command. e.g.
For x = 1 to 1000
If PEEK(64324) = 1 then exit
Next x
So when the 'y' key was pressed, the loop would exit or goto the next command. Can BATCH check a specific address for it's current state and if so, is there any repository or listing somewhere that tells what address is what for things like colors and keys on the keyboard?
In MSDOS you can use the DEBUG tool to get a dump of memory:
SHOWBIOS.BAT
ECHO:d FE00:0000 0040 >debug.txt
ECHO:q >>debug.txt
DEBUG < debug.txt > debug.out
You can run the memory dump thru a script
-d FE00:0000 0040
FE00:0000 41 77 61 72 64 20 53 6F-66 74 77 61 72 65 49 42 Award SoftwareIB
FE00:0010 4D 20 43 4F 4D 50 41 54-49 42 4C 45 20 34 38 36 M COMPATIBLE 486
FE00:0020 20 42 49 4F 53 20 43 4F-50 59 52 49 47 48 54 20 BIOS COPYRIGHT
FE00:0030 41 77 61 72 64 20 53 6F-66 74 77 61 72 65 20 49 Award Software I
-q
Times have changed, indeed, but in fact you could perhaps still do PEEKs and POKEs with the good old Motorola 68k family... because they like the 6502 used memory-mapped I/O.
I could be wrong, but I think computers today largely have abandoned memory-mapped I/O. Instead they'll do something like the Intel 8x86 family. It's been awhile since I took 8086 assembly, though.

Pulling ordered list using array functions in Excel

I have a report in excel that displays the sales results from each employee. The columns are Location, Region, Username & Sales. It is sorted by Sales descending, showing which employee has the best sales in the company.
I am attempting to have an additional sheet per region that displays the results for all employees in that region also sorted by Sales (to avoid sorting the results of the many regions myself everyday).
An example version of the first 12 rows of the Data Sheet:
G H I J K X
Row Location Username Sales Region Region
1 38 John.Doe 85 North1 North1
2 154 John.Smith 83 South2
3 23 E.Williams 83 North1
4 210 M.Williams 79 East5
5 139 Joe.Dawn 77 North2
6 22 Kay.Smith 69 South2
7 51 Jay.Smith 69 South2
8 125 L.Smith 69 East2
9 51 L.Day 69 South2
10 23 23.Guest2 67 North1
11 92 U.Goode 65 North4
I have successfully created an array function that pulls the Sales column of only the results in the specified region.
{=LARGE(SMALL(IF(IF(ISERROR(K:K),"",K:K)=$X$2,J:J),
ROW(INDIRECT("1:"&COUNTIF(K:K,$X$2)))),F2)}
I am attempting now for an array function that pulls the Username that matches the corresponding sales amount in the original array, and also matches the region. I am having trouble when a single region has 'ties' or more than one employee with the same sales that month. Here is what I started with for that function:
=INDEX(I:I,MATCH(1,(Y2=J:J)*($X$1=K:K),0)
but that is having trouble when a single region has multiple users with the same sales. So I am trying a conditional to accomodate, with the function I know that works for singles when there's only one of that sales for that region.
{=IF(COUNTIF($AB$2:AB2,AB2)>1,
INDEX(I:I,
SMALL(IF(J:J=AB2,
IF(K:K=$AB$2,ROW(K:K)-ROW(INDEX(K:K,1,1))+1)),
COUNTIF($AB$2:AB2,AB2))),
INDEX(I:I,MATCH(1,(AC2=J:J)*($AB$2=K:K),0)))}
The inner piece may be sufficient if it worked, excluding the need for the conditional:
{=INDEX(I:I,
SMALL(IF(J:J=AB2,
IF(K:K=$AB$2,ROW(K:K)-ROW(INDEX(K:K,1,1))+1)),
COUNTIF($AB$2:AB2,AB2)))}
I'll use the same function for Username.
Expected results for two regions:
X Y Z AA AB AC AD AE
Region Sales Username Location Region Sales Username Location
North1 85 John.Doe 38 South2 83 John.Smith 154
83 E.Williams 23 69 Kay.Smith 22
67 23.Guest2 23 69 Jay.Smith 51
69 L.Day 51
Since beginning to type this question I have found a work around that includes a few additional columns to complete the calculation, but still wanted to ask this to see if it was possible for knowledge's sake.
With North1 in X2, these are the formulas for Y2:AA2.
=IFERROR(AGGREGATE(14, 6, ($J$2:$J$999)/($K$2:$K$999=X$2), ROW(1:1)), "")
=IFERROR(INDEX($H:$H, AGGREGATE(15, 6, ROW($2:$999)/(($K$2:$K$999=X$2)*($J$2:$J$999=Y2)), COUNTIF(Y$2:Y2, Y2))), "")
=IFERROR(INDEX($H:$H, AGGREGATE(15, 6, ROW($2:$999)/(($K$2:$K$999=X$2)*($J$2:$J$999=Y2)), COUNTIF(Y$2:Y2, Y2))), "")
Fill down as necessary.
With South2 in AB2, copy Y2:AA2 to AC2:AE2 and fill down as necessary.

Is there a pattern in these bitshifts?

I have some Nikon raw files (.nef) which were rendered useless during a USB transfer. However, the size seems fine and only a handful of bits are shifted - by a value of -0x20 (hex) or -32 (dec).
Some of the files could be recovered later with another Computer from the same Card and now I am searching for a solution to recover the other >100 files, which have the same error.
Is there a regular pattern? The offsets seem to be in intervals of 0x800 (2048 in dec).
Differences between the two files
1. /_LXA9414.dump: 13.703.892 bytes
2. /_LXA9414_broken.dump: 13.703.892 bytes
Offsets: hexadec.
84C00: 23 03
13CC00: B1 91
2FA400: 72 52
370400: 25 05
4B9400: AE 8E
641400: 36 16
701400: FC DC
75B400: 27 07
925400: BE 9E
A04C00: A8 88
AC2400: 2F 0F
11 difference(s) found.
Here are more diffs from other files:
http://pastebin.com/9uB3Hx43

MSVS 2010 C: memory detection working as expected

I am working on a C project in MSVS 2010 (meaning I am using malloc, calloc, and free, not the C++ new and delete operators). I need to find a memory leak(s?), so I've followed the steps on http://msdn.microsoft.com/en-us/library/x98tx3cf.aspx to get the program to dump the memory state at the end of the run.
I include the libraries like so:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
I also specify that every exit should display the debug info like so:
_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
But my debug output looks like this:
Detected memory leaks!
Dumping objects ->
{80181} normal block at 0x016B1D38, 12 bytes long.
Data: < 7 7 8 7 > 0C D5 37 00 14 A9 37 00 38 99 37 00
{80168} normal block at 0x016ACC20, 16 bytes long.
Data: < 7 H 7 X 7 \ 7 > A8 FB 37 00 48 E9 37 00 58 C2 37 00 5C AC 37 00
...
According to the article, I should be getting file name and line number output indicating where the leaked memory is allocated. Why is this not happening, and how can I fix it?
Adrian McCarthy commented that I should ensure that the definition _CRT_MAP_ALLOC existed in every compilation unit. While I could not figure out how to define that as a compiler option, I did create a sparse header file that I ensured every compiled file included. This made the debugging functionality work as expected.

Resources