Why are the API's _open, _close, and other standard file i/o functions prefixed with an underscore? Aren't these part of some standard?
open/close are part of some Unix standards, POSIX, SUS, etc. but Windows is not a Unix.
You'll note that the ANSI C standard library functions like fopen do not have the single underscore decoration.
Because Windows isn't a Unix, there may have been a time, long ago, where the Unix style APIs were not available. Because of this, client code could have been written that defined functions like open and close. To maintain compatibility with existing code, when Unix style APIs were added, they could be added with leading underscores because identifiers with leading underscores are reserved for the implementation. In other words, no existing code should be defining a function named _open.
"Portable" code targetting the Unix style apis can then be relatively easily compiled via use of macros (or aliases implemented at the linker level), since that code, targetting unix, knows it didn't define any functions named open/close etc.
Related
I was reading through Windows process APIs, and was left with three questions:
What is the difference between base APIs and shell APIs? I read that shell APIs wrap base APIs e.g. ShellExecute() and ShellExecuteEx() wrap CreateProcess() but fail to understand the distinction.
How are base APIs and Shell APIs different from CRT functions (C Runtime). As again, exec() and spawn() CRT functions wrap CreateProcess() of the base API.
I understand that I can use base APIs and CRT functions from code directly by compiling and linking with the correct header files. How do I make use of Shell APIs?
1) What is the difference between base API's and shell API's?
They do different things. ShellExecute family does things in the same way as the shell, i.e. in the same way as windows explorer. It is not simply a wrapper around CreateProcess. For example, if you pass to ShellExecute the path to a word document, ShellExecute will look up in the registry to find out what is the correct way to open a word document, and do that.
ShellExecute can also do the other "verbs" you see on the Windows context menu, such as edit, print, etc.
2) How are base API's and Shell API's different from CRT functions
CRT functions are implemented on Windows so as to be compatible with the C standard. They are wrappers around CreateProcess, but the reason they exist is to be compatible not to offer additional functionality.
3) How do I make use of Shell API's
To use the shell APIs you simply include the header files and link the correct library, just as with any other API.
For example, ShellExecute:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb762153(v=vs.85).aspx
As you see at the bottom of the page it tells you which file to include and which library to link against.
Requirements
Minimum supported client: Windows XP [desktop apps only]
Minimum supported server: Windows 2000 Server [desktop apps only]
Header: Shellapi.h
Library: Shell32.lib
DLL: Shell32.dll (version 3.51 or later)
Unicode and ANSI names: ShellExecuteW (Unicode) and ShellExecuteA
(ANSI)
The shell (aka Windows Explorer) adds an extra layer of functionality. It manages file associations, it knows what EXE should be started when you ask it to "run" a document. If you pass the name of, say, a .html file then ShellExecuteEx() can figure out that a browser needs to be started. It also supports verbs, different things you can do with a document. Other than "open", the default verb, the "print" and "edit" verbs are common for example.
That's missing from CreateProcess(), it only knows how to start an executable file. Still with lots of options, review the MSDN docs for the security attributes and creation flag options.
Lots of those whistles are missing from the CRT functions, they work on any operating system so you cannot do much beyond specifying the executable name and the command line arguments.
Command Prompt, also known as cmd.exe or cmd (after its executable
file name), is the command-line interpreter on Windows NT, Windows CE,
OS/2 and eComStation operating systems. It is the counterpart of
COMMAND.COM in DOS and Windows 9x systems (where it is also called
"MS-DOS Prompt"), and analogous to the Unix shells used on Unix-like
systems.
Source: Wikipedia
I have searched everywhere but could not get an answer for this question.
Each website focuses on the fact that batch language is used in cmd.exe but I could not find the language in which it is written.
So my question is:
What is the language that was used to write command-prompt or cmd.exe in Windows?
The file, when opened in a text editor, contains the path onecore\base\cmd\maxpathawarestring.cpp, which would indicate that at least one source file is written in C++.
Addendums from Hans Passant:
The imports it depends on makes it is likely to be a mix of C and C++. CRT functions like longjmp, calloc, free indicate C code, might well be ancient and hark back to the command.com days. It clearly also uses C++ exception handling, C++ is their weapon of choice for all recent code development. Mixing is not uncommon.
And eryksun:
under a debugger it's obvious that recent additions to CMD have been written in C++. x cmd!*::* shows significant use of the C++ std namespace
[...]
But CMD is still mostly C, not C++. Its commands and support functions are implemented as C functions such as eExit, eChdir, ParseStatement, SearchForExecutable, and ExecPgm. They haven't ported all of this old C code to an OOP design.
So I'd go with a mix of C and C++.
As officially confirmed by MS' Rich Turner, originally it's written in C
Cmd is a Win32 app written entirely in 'C' - this is important since one of the key goals of NT was to be portable across many different processor and machine architectures
https://devblogs.microsoft.com/commandline/rumors-of-cmds-death-have-been-greatly-exaggerated/
but parts of it were migrated to C++ as of now
Inside the Windows Console
Windows Console is a traditional Win32 executable and, though it was originally written in 'C', much of the code is being migrated to modern C++ as the team modernizes and modularizes Console's codebase.
For those who care about such things: Many have asked whether Windows is written in C or C++. The answer is that - despite NT's Object-Based design - like most OS', Windows is almost entirely written in 'C'. Why? C++ introduces a cost in terms of memory footprint, and code execution overhead. Even today, the hidden costs of code written in C++ can be surprising, but back in the late 1990's, when memory cost ~$60/MB (yes … $60 per MEGABYTE!), the hidden memory cost of vtables etc. was significant. In addition, the cost of virtual-method call indirection and object-dereferencing could result in very significant performance & scale penalties for C++ code at that time. While one still needs to be careful, the performance overhead of modern C++ on modern computers is much less of a concern, and is often an acceptable trade-off considering its security, readability, and maintainability benefits ... which is why we're steadily upgrading the Console’s code to modern C++.
Windows Command-Line: Inside the Windows Console
If you look into the latest Windows Console’s internals structure you can see that it uses Map, Collection which suggests that it likely uses some C++/CX
From the top (original buffer's blue boxes):
ScreenInfo – maintains information about the viewport, etc., and contains a TextBuffer
TextBuffer – represents the Console’s text area as a collection of rows
Row – uniquely represents each CharRow in the console and the formatting attributes applied to each row
CharRow – contains a collection of CharRowCells, and the logic and state to handle row wrapping & navigation
CharRowCell – contains the actual cell’s text, and a DbcsAttribute byte containing cell-specific flags
In case you're interested then conhost.exe has also been open sourced, under the form of the new Windows terminal
The Windows console host, conhost.exe, is Windows' original command-line user experience. It implements Windows' command-line infrastructure, and is responsible for hosting the Windows Console API, input engine, rendering engine, and user preferences. The console host code in this repository is the actual source from which the conhost.exe in Windows itself is built.
https://github.com/microsoft/terminal
You can find more pretty good articles with detailed information in the Windows command line blog
Is it possible to create a new, arbitrary, file namespace scheme in Windows?
As best I understand, Windows currently understands two or three file system or file-system-like namespace schemes:
The namespace scheme we all know and love, eg, C:\path\to\file.
UNC paths, eg, \\server\path\to\file
One, perhaps uncommon scheme - the Windows NT Object Manager, eg, \\.\Device\COM1 - see WinObj on SysInternals, usually accessed by programs by calling CreateFile, though this is not really a file system.
Is it possible to implement a custom namespace scheme that would be universally, automatically used by the rest of the operating system? Perhaps a filter driver or some other specialized kernel-mode driver? I'm out of my league here, but I'm genuinely curious.
I don't have anything concrete, but lets say I wanted to implement a kernel driver that, not only understands how to read and write OpenVMS file systems, but also implements some sort of filter driver so that userland programs could use standard File-11 syntax to access such a filesystem.
For example, an existing program calls OpenFile("[DIR1.DIR2.DIR3]FILE.EXT;10"); and somehow a custom handler deals with it transparently, and lo, notepad can read and write VMS files. More importantly, perhaps, some ported program that expects OpenVMS File-11 path strings just works. Simply mapping the OpenVMS file system into the regular windows file system as D:\dir1\dir2\file.ext would be insufficient.
I should clarify that my OpenVMS reference is just an example; I'd be looking for a more generic solution. This could be for OpenVMS File-11, MVS, standard unix syntax ala /path/to/thing, or something I just cooked up myself.
I'm aware of shell-based namespace extensions, and compatibility layers like cygwin, but that's not what I'm looking for.
So SO, what do you think? Is this possible? Where do you start?
I would like to use a non-unicode library from my unicode-built MFC application. However, I'm not sure whether there is a possibility of occurring events such as unintended memory allocations, string handling inside the non-unicode library.
Please explain any implications or provide a resource page.
Whether or not an application is Unicode is a compile-time, not a run-time, distinction - there is no inherent reason why a Unicode executable can't load an ANSI DLL. If the application and DLL both used MFC they would be linked to different MFC runtimes, which could cause problems, but as that isn't the case you should be fine.
Where you need to take care is to ensure that any string data transferred between the DLL and the application are interpreted consistently. Mostly this just means converting between ANSI and Unicode as necessary, and Windows provides API functions which allow you to do this easily enough.
You should, however, check the header files for any data types that are interpreted differently when compiling for Unicode than when compiling for ANSI. For example, if one of the DLL functions was declared as
DWORD process_string(TCHAR * string)
then the non-unicode library would interpret TCHAR as char, but your application would interpret it as wchar_t, hiding the fact that you need to convert the string to ANSI before calling the function.
I am writing a program that handles mostly Unicode text. The C standard library function 'fopen' provides for writing the characters to file in utf-8 format by including in the mode string argument "..., ccs=utf-8". It seems that the Windows API 'CreateFile' does give such provision. Must I use 'fopen' then?
This is Specific to programming under Windows, using Visual Studio, and Microsoft tools. My personal advice is to not to use fopen with the extended syntax, otherwise later there will be compatibility issues when porting your application to other operating systems. When under Windows, do the Windows way, use CreateFile.
The contents of the file are defined not by the file-opening function, but the actual data you write. After you get the file handle (either by fopen or CreateFile), you can write in UTF-8, or ANSI, or whatever you like.
Note that some encodings require a special bit at the beginning of the file.