How do I inform Windows that I’m writing a binary file?

The Old New Thing (Raymond Chen) News

Summary

This article explains that Windows does not have a built-in concept of binary vs. text mode at the OS level; such distinctions are handled by runtime libraries like the C runtime. It clarifies that all files are treated as bytes by Windows and that content transformations must be done manually or via libraries.

<p>A customer wanted to know how to inform Windows that they were opening a file in text mode, as opposed to binary mode. That way, Windows can perform text conversions as necessary, like adding carriage returns before linefeeds, or converting ASCII to Unicode.</p> <p>Windows doesn&#8217;t know whether your file is binary or text. As far as Windows is concerned, it&#8217;s just a bunch of bytes, and it&#8217;s up to you to interpret it. So in a sense, all files are binary files. If you want to insert carriage returns before linefeeds, you will have to do it yourself.</p> <p>Now, it is often the case that you are using a higher level library, like the C runtime, in which case you can ask the library to do it for you, such as opening the file in <tt>"w"</tt> mode to indicate that the runtime should treat the file as a text file, or in <tt>"wb"</tt> to open as a binary file. But this work happens in the runtime library, not in Windows itself. The runtime library performs the necessary transformations and passes binary data to Windows. There are no further transformations once the data hits <code>Write­File</code>.</p> <p>&#8220;But wait, there&#8217;s an old MS-DOS ioctl <a href="https://www.ctyme.com/intr/rb-2821.htm">AH=4401h (Set device information)</a> where you pass flags in DX, and <a href="https://www.ctyme.com/intr/rb-2820.htm"> bit 5 is the raw (binary) mode bit</a>. So what&#8217;s the Windows version of this ioctl?&#8221;</p> <p>If you look more closely, that MS-DOS ioctl applies only to character devices. <a href="https://github.com/microsoft/MS-DOS/blob/2d04cacc5322951f187bb17e017c12920ac8ebe2/v2.0/source/XENIX2.ASM#L470"> If you try to use it on a disk file, you get <code>ERROR_<wbr />INVALID_<wbr />FUNCTION</code></a>.</p> <pre>ioctl_check_permissions: CMP AL,2 JAE ioctl_control_string CMP AL,0 MOV AL,BYTE PTR ES:[DI+sf_fcb+fcb_devid] JZ ioctl_read ; read the byte OR DH,DH JZ ioctl_check_device ; can I set with this data? error error_invalid_data ; no DH &lt;&gt; 0 ioctl_check_device: TEST AL,devid_ISDEV ; can I set this handle? <span style="border: solid 1px currentcolor;">JZ ioctl_bad_fun ; no, it is a file.</span> ... ioctl_bad_fun: error error_invalid_function </pre> <p>This IOCTL can be used to tell the console things like whether to perform line buffering on input. The Win32 equivalent is <code>Set­Console­Mode</code>, roughly corresponding to the Unix <tt>stty</tt>.</p> <p>If you want to perform content transformations on files, you&#8217;ll have to do it yourself, or ask someone else (like the runtime library) to do it for you.</p> <p>The post <a href="https://devblogs.microsoft.com/oldnewthing/20260504-00/?p=112296">How do I inform Windows that I&#8217;m writing a binary file?</a> appeared first on <a href="https://devblogs.microsoft.com/oldnewthing">The Old New Thing</a>.</p>
Original Article
View Cached Full Text

Cached at: 05/16/26, 03:32 AM

# How do I inform Windows that I'm writing a binary file? - The Old New Thing Source: [https://devblogs.microsoft.com/oldnewthing/20260504-00?p=112296](https://devblogs.microsoft.com/oldnewthing/20260504-00?p=112296) A customer wanted to know how to inform Windows that they were opening a file in text mode, as opposed to binary mode\. That way, Windows can perform text conversions as necessary, like adding carriage returns before linefeeds, or converting ASCII to Unicode\. Windows doesn’t know whether your file is binary or text\. As far as Windows is concerned, it’s just a bunch of bytes, and it’s up to you to interpret it\. So in a sense, all files are binary files\. If you want to insert carriage returns before linefeeds, you will have to do it yourself\. Now, it is often the case that you are using a higher level library, like the C runtime, in which case you can ask the library to do it for you, such as opening the file in"w"mode to indicate that the runtime should treat the file as a text file, or in"wb"to open as a binary file\. But this work happens in the runtime library, not in Windows itself\. The runtime library performs the necessary transformations and passes binary data to Windows\. There are no further transformations once the data hits`Write­File`\. “But wait, there’s an old MS\-DOS ioctl[AH=4401h \(Set device information\)](https://www.ctyme.com/intr/rb-2821.htm)where you pass flags in DX, and[bit 5 is the raw \(binary\) mode bit](https://www.ctyme.com/intr/rb-2820.htm)\. So what’s the Windows version of this ioctl?” If you look more closely, that MS\-DOS ioctl applies only to character devices\.[If you try to use it on a disk file, you get`ERROR\_INVALID\_FUNCTION`](https://github.com/microsoft/MS-DOS/blob/2d04cacc5322951f187bb17e017c12920ac8ebe2/v2.0/source/XENIX2.ASM#L470)\. ``` ioctl_check_permissions: CMP AL,2 JAE ioctl_control_string CMP AL,0 MOV AL,BYTE PTR ES:[DI+sf_fcb+fcb_devid] JZ ioctl_read ; read the byte OR DH,DH JZ ioctl_check_device ; can I set with this data? error error_invalid_data ; no DH <> 0 ioctl_check_device: TEST AL,devid_ISDEV ; can I set this handle? JZ ioctl_bad_fun ; no, it is a file. ... ioctl_bad_fun: error error_invalid_function ``` This IOCTL can be used to tell the console things like whether to perform line buffering on input\. The Win32 equivalent is`Set­Console­Mode`, roughly corresponding to the Unixstty\. If you want to perform content transformations on files, you’ll have to do it yourself, or ask someone else \(like the runtime library\) to do it for you\. ### Category ### Topics ## Author ![Raymond Chen](https://devblogs.microsoft.com/oldnewthing/wp-content/uploads/sites/38/2019/02/RaymondChen_5in-150x150.jpg) Raymond has been involved in the evolution of Windows for more than 30 years\. In 2003, he began a Web site known as The Old New Thing which has grown in popularity far beyond his wildest imagination, a development which still gives him the heebie\-jeebies\. The Web site spawned a book, coincidentally also titled The Old New Thing \(Addison Wesley 2007\)\. He occasionally appears on the Windows Dev Docs Twitter account to tell stories which convey no useful information\.

Similar Articles

How do I use Win32 structures from the Windows Runtime?

The Old New Thing (Raymond Chen)

This article explains how to use Win32 structures in the Windows Runtime by declaring shadow structures with the same layout, including specific examples and alternatives for common structures.

Theseus: translating win32 to wasm

Lobsters Hottest

Translates Windows executables (win32/x86) to WebAssembly to run in the browser, discussing challenges like blocking vs async design.

Microsoft’s new developer-optimized Windows embraces Linux even more

The Verge

Microsoft announced a developer-optimized Windows 11 experience at Build, including Coreutils for Windows (native Linux-like utilities), WSL containers for easy Linux container management, an experimental Intelligent Terminal with AI integration, and Windows Developer Configurations for quick setup.